2011-01-16 39 views
29

He creado la siguiente función:No se puede convertir de 'grupo Método' a 'System.Action <object>' error

public void DelegatedCall(Action<Object> delegatedMethod) 

Y se define el siguiente método

public void foo1(String str) { } 

Sin embargo, cuando intento llamar DelegateCall con foo1:

DelegatedCall(foo1); 

... consigo º e error de compilador siguiente:

Argument 1: cannot convert from 'method group' to 'System.Action<object>'

¿Cuál es la razón de este error y cómo puedo corregirlo? Desafortunadamente, el envío de foo1 a Action no es una opción.

+0

Relacionado: [¿Qué es un grupo de métodos en C#?] (Http://stackoverflow.com/q/886822/1497596) – DavidRR

Respuesta

20

DelegatedCall espera un delegado que tome cualquier object como argumento. Pero su función foo1 que está pasando a DelegatedCall solo puede hacer frente a un argumento string. Por lo tanto, la conversión no es segura y, por lo tanto, no es posible.

Los parámetros de entrada son contra-variant, pero su código necesita covariance. (Ver Difference between Covariance & Contra-variance.)

Usted puede hacer DelegatedCall genérica:

DelegatedCall<T>(Action<T> action) 

... o tiene que tomar cualquier delegado:

DelegatedCall(Delegate action) 

Pero entonces implementando es feo y requiere reflexión. Tampoco verifica que la función tenga solo un parámetro en tiempo de compilación.

+0

¿Conoces alguna forma de crear un código de este tipo? Quiero que DelegateCall tenga la capacidad de recibir una función que reciba cualquier parámetro de cualquier tipo (String, bool, List ...) – Jonathan

+2

¿Se puede hacer genérico? – CodesInChaos

+0

Desafortunadamente no – Jonathan

9

La varianza no funciona de esa manera; necesitaría

DelegatedCall(obj => foo1((string)obj)); 

Como incluso en 4.0 no creerá que cada objeto es una cadena.

Tenga en cuenta que si era foo1(object) y Action<string> (es decir, al revés) que probablemente funcionaría (en 4.0), ya que cada cadena es un objeto.

+1

El revés funciona incluso antes de 4.0. Al convertir desde un método, la variación de grupo estaba disponible incluso en versiones anteriores. – CodesInChaos

+0

Ok, de todos modos, puedo hacer que esto funcione: Quiero que DelegateCall tenga la capacidad de recibir una función que reciba cualquier parámetro de cualquier tipo (String, bool, List ...). Cualquier ayuda sería apreciada – Jonathan

Cuestiones relacionadas