Wie erstellen Sie einen Ausdruck.Lambda, wenn ein Typ erst zur Laufzeit bekannt ist?

Dies ist am besten zu erklären, mithilfe von code. Ich habe eine generische Klasse, die eine Methode hat, die eine Ganzzahl zurückgibt. Hier ist eine einfache version für die Zwecke zu erklären...

public class Gen<T>
{
    public int DoSomething(T instance)
    {
        //Real code does something more interesting!
        return 1;
    }
}

Zur Laufzeit benutze ich die Reflexion zu entdecken, die Art von etwas, und dann wollen, erstellen Sie eine Instanz meiner Klasse Gen für diesen bestimmten Typ. Das ist einfach genug, und so geschehen...

Type fieldType = //This is the type I have discovered
Type genericType = typeof(Gen<>).MakeGenericType(fieldType);
object genericInstance = Activator.CreateInstance(genericType);

Möchte ich nun einen Ausdruck erstellen, der als parameter eine Instanz des generischen Typs und ruft dann die Methode DoSomething in der Art. So möchte ich den Ausdruck für die effektive Ausübung...

int answer = genericInstance.DoSomething(instance);

...außer, dass ich nicht die 'Instanz', bis irgendwann später in der Laufzeit und der genericInstance ist der generierte Typ wie oben zu sehen ist. Mein Versuch auf die Schaffung der Lambda-Ausdruck für dieses ist wie folgt...

MethodInfo mi = genericType.GetMethod("DoSomething", 
                                      BindingFlags.Instance | BindingFlags.Public);

var p1 = Expression.Parameter(genericType, "generic");
var p2 = Expression.Parameter(fieldType, "instance");

var x = Expression.Lambda<Func<genericType, fieldType, int>>
            (Expression.Call(p1, mi, p2), 
             new[] { p1, p2 }).Compile();

...so dass später auf, die ich anrufen kann es mit etwas in dieser Art...

int answer = x(genericInstance, instance);

Natürlich, Sie nicht Func mit Instanz-Parameter, und so habe ich keine Ahnung wie ich das parametrisieren der Lambda-generation. Irgendwelche Ideen?

InformationsquelleAutor Phil Wright | 2011-10-18

Schreibe einen Kommentar