2011-04-28 13 views
14

Estoy tratando de escribir un método para devolver una instancia de sí mismo. El pseudo código es¿Cómo devuelvo una función de delegado o una expresión lambda en C#?

Func<T,Func<T>> MyFunc<T>(T input) 
{ 
    //do some work with input 
    return MyFunc; 
} 

parece bastante simple. Pero estoy teniendo problemas para definir el tipo de devolución. El tipo de retorno debe ser un delegado

which takes T as parameter, then returns a function 
which takes T as parameter, then returns a function 
which takes T as parameter, then returns a function 

    ...recursive definition 

Estoy seguro de que había algo sutil que no me di cuenta. ¿Alguien puede señalarlo por mí? Gracias.

+0

Me pregunto por qué está tratando de hacer esto –

+0

estaba escribiendo un método de utilidad, que es estático dentro de una clase estática También quiero tener la funcionalidad "fluida" MyFunc (a) .MyFunc (b) ... pero dado que estoy dentro de una clase estática. No es posible devolver una instancia de la clase en sí. –

Respuesta

15

Usted puede hacerlo de esta manera:

delegate F<T> F<T>(T obj); 

F<T> MyFunc<T>(T obj) 
{ 
    return MyFunc; 
} 

Pero es bastante inútil. La única cosa que realmente puede hacer es algo como esto, lo cual es raro:

void Main() 
{ 
    MyFunc(1)(2)(3)(4); 
} 

delegate F<T> F<T>(T obj); 

F<T> MyFunc<T>(T obj) 
{ 
    Console.WriteLine(obj); 
    return MyFunc; 
} 
+0

No sé por qué no pensé en eso ... +1. – Justin

+1

Tengo bloque de código de comprobación de errores para cada método que estoy implementando. Y todos son muy similares, como si (a == null) arrojara una nueva NullArgumentException; entonces, de hecho es útil tener ErrorCheck (a) (b) (c) (d); De esta forma puedo hacer todo el control de errores en una línea. El código será mucho menos desordenado. Voy a probar tu solución ahora mismo. Será excelente si funciona :) –

+0

Funcionó como un encanto. Gracias amigo. –

2

Esto suena como un iterador. Si se puede refactorizar su código a ser algo así como:

Dónde T es su tipo de entrada y P es su tipo de resultado. No es idéntico, pero debería hacer el trabajo.

Editar: Si, por el contrario, quiere una interfaz fluida, el patrón es bastante inamovible: crea una clase no estática y la devuelve de cada función (que no es estática) a la que llama. La versión no estática de una clase estática se llama singleton y puede usarla para este patrón.

+0

En realidad estoy tratando de utilizar este método de mi utilidad para realizar una tarea común para implementar la función LinQ2Object, como Where, Select, etc. Tu código está bien, pero esa es la parte del trabajo "real". Mi método de utilidad tiene la intención de verificar errores antes de ejecutar esta parte. –

1

No estoy seguro de lo que está tratando de lograr, pero como un ejercicio intelectual "¿puedo devolver un método que se devuelve a sí mismo?" las siguientes obras:

object MyFunc<T>(T input) 
{ 
    Func<T, object> returnValue = MyFunc; 
    return returnValue; 
} 

Como usted dice, no se puede tener el método devuelve un Func ya que esto significaría que el tipo de retorno de dicho delegado tendría que ser un Func que devuelve un Func que devuelve un Func etc. ...

La única forma de salir de esta infinita recisión que puedo ver es hacer que devuelva object, lo que requiere que el emisor de la llamada emita el tipo correcto.

Editar: Porges respuesta es mejor ...

+0

Como escribí en la respuesta para porges. Estaba escribiendo código de comprobación de errores que se repite mucho. Al hacer esto, el código es mucho más terser. –

+0

@WeiMa Una alternativa podría haber sido usar 'params' - Personalmente prefiero que el manejo de mis errores sea explícito. Incluso si es más detallado, generalmente lo hace más claro para leer. En cualquier caso, esta fue una pregunta interesante. – Justin

+0

O regrese dinámico si usa .NET4 para evitar tener que emitir. – Michael

Cuestiones relacionadas