2012-02-22 23 views
6

Tengo código de legado que define el siguiente ayudante¿Cómo convierto delegar la función R <T,R> (T t) en Func <T,R>?

public delegate R Function<T, R>(T t); 

Pero quiero suministrar un intento de Func<T,TResult>

fundición fallan para compilar

No se puede convertir tipo 'System.Func<T,TResult>' a ' Rhino.Mocks.Function<T,TResult> '

Hay una forma t no solo compila, sino que funciona en tiempo de ejecución?

Respuesta

9

El problema es que está intentando combinar dos tipos de delegados diferentes: Func<T, TResult> y Function<T, TResult>. Aunque tienen la misma firma, son tipos diferentes y, por lo tanto, incompatibles.

Usa una lambda para crear una capa de conversión entre las dos.

Func<T, TResult> func = ...; 
TheMethod(x => func(x)); 
+0

ah, a la derecha. escribir cosas a menudo es mi último recurso. Se aceptará una vez que lo permita. – Maslow

8

Se puede crear una lambda como sugiere JaredPar, o pasar uno al constructor de la otra:

Func<int, string> f1 = i => i.ToString(); 
Function<int, string> f2 = new Function<int, string>(f1); 
+1

Gracias a @EricLippert por arreglar la expresión lambda; Pasé parte de la tarde trabajando en F #, que usa '->' en lugar de '=>'. – phoog

9

Jared y phoog son ambas correctas. Una tercera manera de hacer la misma cosa, sólo para redondear hacia fuera, es:

Func<int, string> func = i => i.ToString(); 
Function<int, string> function = func.Invoke; 

Es decir, el nuevo delegado es un delegado a el método de invocación del primer delegado, que tiene la firma correcta.

Que uno tiene que hacer esto es molesto en el extremo. Si hoy diseñamos el tiempo de ejecución desde cero, sabiendo lo que ahora sabemos sobre cómo las personas usan los tipos de delegados, creo que podría haber uno integrado en el tipo de delegado para cada firma (como hay uno "single tipo de matriz dimensional de enteros), o que existiría una "identidad estructural" entre los tipos de delegados. La próxima vez que diseñe el sistema de tipos para una máquina virtual, tenga esto en cuenta.

+0

No estoy seguro si el tiempo de ejecución es el nivel correcto para atacar este problema. En particular, no estoy seguro de qué tan bien esos cambios interactuarían con los nombres de los parámetros. – CodesInChaos

+0

Si la implementación de esta función fuera gratuita (es decir, no requiriera pruebas, aparte el tiempo del desarrollador de otras características, comenzara en 0 puntos en lugar de -100 puntos, etc.), ¿habría algún inconveniente importante para implementarlo? – Brian

+0

Si entiendo correctamente, dado que no compila, no ayudaría que el tiempo de ejecución esté bien con él. – Maslow

Cuestiones relacionadas