2012-06-12 6 views
6

Tengo muchos métodos similares a esta:parámetro "out" (referencia) con Acción <>

void GetColorSky(out float r, out float g, out float b) 
void GetColorGround(out float r, out float g, out float b) 

"similares" que significa que tienen exactamente la misma cabecera del método excluyendo el nombre del método. También tengo varios controles "colourPicker", que aceptan valores R, G, B.

Estoy tratando de crear un método que acepta un método como uno de sus parámetros, así:

UpdateColourPicker(ColorPicker cp, CustomMethod cMethod) 

y lo llaman de la siguiente manera:

UpdateColourPicker(cpSky, GetColorSky) 
UpdateColourPicker(cpGround, GetColorGround) 

¿Cuál es la sintaxis correcta para out y Action juntos? Miré this question pero todavía no lo he logrado.

Gracias!

+0

Como regla general, sería mejor que sus funciones devuelvan valor en lugar de usar params ya que hacen que las funciones no se puedan componer – Ankur

+0

¿Qué hay de malo en simplemente declarar esos métodos como 'Color GetColorSky()'? Todos esos parámetros parecen innecesarios para mí. – Botz3000

+0

@Ankur No tengo otra opción. Las funciones no provienen de C# sino de una DLL externa, así que tengo que usar referencias. Gracias por el consejo sin embargo. – David

Respuesta

3

Tomando el ejemplo de esa respuesta vinculado, esto va a funcionar:

public delegate void GetColorDel(out float r, out float g, out float b); 

void UpdateColourPicker(ColorPicker cp, GetColorDel cMethod) { } 

UpdateColourPicker(cpSky, GetColorSky); 
UpdateColourPicker(cpGround, GetColorGround); 

Por desgracia, como se indica en la respuesta a la pregunta que enlace, Action y Func no trabajar con out y ref. Esto es simplemente porque Action y Func son solo definiciones de delegado indicadas (bastantes veces para ofrecer diferentes sobrecargas) con genéricos en el BCL. Agregar ref y out variantes causaría rápidamente errores de compilación de redefinición.

La muestra completa:

class Program 
{   
    public delegate void GetColorDel(out float r, out float g, out float b); 

    static void Main(string[] args) 
    { 
     UpdateColourPicker(null, GetColorSky); 
     UpdateColourPicker(null, GetColorGround); 

     Console.Read(); 
    } 

    static void GetColorSky(out float r, out float g, out float b) 
    { 
     r = g = b = 0f; 
     Console.WriteLine("sky"); 
    } 

    static void GetColorGround(out float r, out float g, out float b) 
    { 
     r = g = b = 0f; 
     Console.WriteLine("ground"); 
    } 

    static void UpdateColourPicker(object cp, GetColorDel cMethod) 
    { 
     float r, g, b; 
     cMethod(out r, out g, out b); 
    } 
} 
+0

Quiere saber cómo usar uno de los delegados 'Action'. – leppie

+0

@leppie: Ya le dijiste al OP que 'out' no es compatible con tipos genéricos, por lo que claramente sabes que no puedes usar 'out' con delegados 'Action <>'. No estoy seguro de a qué va tu comentario. – Gabe

+0

@leppie Lo sé, y eso se responde en su propia pregunta vinculada. Voy a enmendar para ser más claro. –

1

Si desea definir un delegado genérico con parámetros OUT, debe hacerse así:

delegate void ActionWithOutparameter<T>(out T x); 
delegate void ActionWithOutparameter<T1, T2>(out T1 x, out T2 y); 
// ... 

Es evidente que las Action y Func delegados en el BCL no coincide con esta firma.

Cuestiones relacionadas