2009-03-18 4 views
15

necesito para poner en práctica el método:creación de tiempo de ejecución de genéricos Func <T>

object GetFactory(Type type); 

Este método tiene que devolver un Func <T> donde typeparam 'T' es el 'tipo'.

Entonces, mi problema es que no sé cómo crear un Func <? > en tiempo de ejecución utilizando la reflexión. Activator.CreateInstance no funciona porque no hay constructores en los delegados.

¿Alguna idea?

Respuesta

23

Utiliza Delegate.CreateDelegate, es decir, a partir de MethodInfo; A continuación, he no modificable, pero se usaría algo de lógica, o Expression, para obtener el método de creación real:

using System; 
using System.Reflection; 
class Foo {} 

static class Program 
{ 
    static Func<T> GetFactory<T>() 
    { 
     return (Func<T>)GetFactory(typeof(T)); 
    } 
    static object GetFactory(Type type) 
    { 
     Type funcType = typeof(Func<>).MakeGenericType(type); 
     MethodInfo method = typeof(Program).GetMethod("CreateFoo", 
      BindingFlags.NonPublic | BindingFlags.Static); 
     return Delegate.CreateDelegate(funcType, method); 
    } 
    static Foo CreateFoo() { return new Foo(); } 
    static void Main() 
    { 
     Func<Foo> factory = GetFactory<Foo>(); 
     Foo foo = factory(); 
    } 
} 

Para métodos no estáticos, hay una sobrecarga de Delegate.CreateDelegate que acepte la instancia de destino .

+0

Mark, en realidad no sé qué es T. Si supiera qué es T, sería fácil. –

+0

¿Quiere decir dentro del método no genérico? Actualizaré ... –

+0

Modifiqué la pregunta para expresar mejor mi problema. –

0

Creo que el enfoque habitual sería hacer que la versión "tonta" sea lo que suplantas en runtme, y luego proporcionar un método de extensión auxiliar para proporcionar la versión tipo segura encima.

+0

Entonces, esto está en las entrañas de un contenedor IoC, y tengo que devolver el objeto como una dependencia fuertemente tipada, no necesariamente sabiendo que lo que se solicitó fue un Func (podría ser un URI o una cadena). –

0

puede crear objetos de expresión en lugar de un func y compilar() la expresión para obtener un delegado de Func.

Cuestiones relacionadas