2009-03-18 9 views
15

Ich brauche das Verfahren zu implementieren:Runtime Erstellung von generischen Func <T>

object GetFactory(Type type); 

Diese Methode benötigt ein Func <T> wo typeparam 'T' zurückzukehren ist der 'Typ'.

Also, mein Problem ist, dass ich nicht weiß, wie man eine Func <erstellen?> zur Laufzeit mit Reflexion. Activator.CreateInstance funktioniert nicht, da keine Konstruktoren für Delegaten vorhanden sind.

Irgendwelche Ideen?

Antwort

23

Sie verwenden Delegate.CreateDelegate, d.h. von einem MethodInfo; unten, habe ich hart codiert, aber Sie würden eine gewisse Logik verwenden oder Expression, die eigentliche Erstellungsmethode zu erhalten:

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(); 
    } 
} 

Für nicht-statische Methoden gibt es eine Überlastung von Delegate.CreateDelegate, die die Zielinstanz akzeptiert .

+0

Mark, ich weiß eigentlich nicht was T ist. Wenn ich wüsste, was T ist, wäre das einfach. –

+0

Sie meinen innerhalb der nicht-generischen Methode? Ich werde aktualisieren ... –

+0

Ich änderte die Frage, um mein Problem besser zu erklären. –

0

Ich denke, der übliche Ansatz wäre, die "dumme" Version zu der Sache zu machen, die Sie bei runtme vortäuschen, und dann eine Hilfserweiterungsmethode bereitzustellen, um die typsichere Version darüber zu liefern.

+0

Also, das ist in den Tiefen eines IoC-Containers, und ich muss das Objekt als stark typisierte Abhängigkeit zurückgeben, nicht unbedingt wissen, dass was angefordert wurde, war ein Func (es könnte ein Uri oder String sein). –

0

können Sie Expression-Objekte anstelle eines Func erstellen, und kompilieren() den Ausdruck, um einen Func-Delegaten zu erhalten.

Verwandte Themen