2009-12-24 13 views
18

me gustaría escribir una función como la siguiente¿Es posible pasar un grupo de métodos arbitrario como parámetro a un método?

// The type 'MethodGroup' below doesn't exist. This is fantasy-code. 
public void MyFunction(MethodGroup g) 
{ 
    // do something with the method group 
} 

La tarde, que podría llamar MyFunction con cualquier grupo método. Algo como esto.

MyFunction(Object.Equals) 

Si me comprometo a una firma, entonces las cosas funcionan bien.

public void MyFunction(Func<object, object, bool> f) 
{ 
    // do something with known delegate 
} 
... 
MyFunction(Object.Equals) 

El grupo método Object.Equals es coaccionado feliz en la conocida Func<object, object, bool> tipo de delegado, pero no quieren comprometerse con una firma en particular. Me gustaría pasar cualquier grupo de métodos al MyFunction.

grupos método no se pueden convertir a System.Object

public void MyFunction(object o) 
{ 
    // do something with o 
} 
... 
MyFunction(Object.Equals) // doesn't work 

Creo que todo el mundo ha olvidado los frenos en una llamada al método y descubrió esto en algún momento. Espero que esto no signifique que los grupos de métodos no estén (o no se puedan convertir) en objetos de primera clase.

No creo que las expresiones de Linq darán la clase de generalidad que estoy buscando, pero ciertamente me podría estar perdiendo algo.

También debería mencionar que estaría bien si el grupo de métodos contenía sobrecargas, siempre que tenga una forma de inspeccionar el grupo de métodos.

¿Qué haría con un grupo de métodos?Podría imprimir todas las firmas de todos los métodos del grupo (sobrecargas, métodos de extensión, etc.), o podría 'invocar' al grupo con algunos argumentos (si es posible, resuelva la sobrecarga correcta en el grupo). Hay otras maneras de hacer estas cosas, pero son algunas de las cosas que podría querer hacer con un grupo de métodos.

Como han mencionado varias personas, puedo aceptar un Delegate, y enviarlo a un tipo de delegado conocido particular cuando llamo al MyFunction.

public void MyFunction(Delegate d) 
{ 
    // do something with d 
} 
... 
MyFunction((Func<object, object, bool>)Object.Equals) 

Pero esto no es lo mismo que pasar todo el grupo de métodos. Esto selecciona un método del grupo y lo convierte en un delegado particular. Realmente me gustaría pasar todo el grupo de una vez.

Respuesta

7

Puede pasar un delegado:

public void MyFunction(Delegate d) 
{ 
    // do something with the method group 
} 

Sin embargo, tendrá que especificar el tipo de delegado al llamar al método:

MyFunction(new Func<object, object, bool>(Object.Equals)); 

Nota: el código anterior no está pasando un grupo método, pero un único método ... No creo que sea posible pasar un grupo de métodos. Por qué querrías hacer eso ?

8

Creo que una pregunta importante aquí es: ¿Qué harías con un grupo de métodos si alguna vez se le puede pasar uno?

tener en cuenta, un grupo método es sólo un nombre para un conjunto de métodos - puede haber uno o más - y que puede haber sobrecargas o métodos de extensión. Los grupos de métodos no son un concepto preservado en código compilado, el compilador admite conversiones de grupos de métodos a delegados, pero para que esto sea posible el compilador debe poder resolver sin ambigüedad exactamente qué método pretende pasar.

Los grupos de métodos solo son válidos como parámetros para las funciones si la función define claramente la firma del método. Entonces, por ejemplo: public void MyFunction(Func<int> f) se puede pasar un grupo de métodos.

Lo más cerca que se puede llegar es escribir una función que acepta el tipo Delegado:

public void MyFunction(Delegate d) { ... } 

pero todavía no será capaz de pasar a grupos de métodos de porque no hay conversión del grupo método para delegar. Tendrá que echar a una firma del delegado especial:

// call MyFunction with a particular delegate 
MyFunction((Func<string>)myObj.ToString); // method group conversion may occur 
+10

Para responder a su pregunta, me gustaría tener su nombre y registrarla. Todos los métodos en un grupo de métodos tienen el mismo nombre y el mismo objeto de destino. Hay muchos usos – skrebbel

1

Creo que se podría usar la firma así:

MyFunc<T>(EventHandler<T> newDelegate) 
{ 
    object storedDelegate = newDelegate; 
    // after that you can use storedDelegate later 
} 
Cuestiones relacionadas