Questo è meglio spiegato usando il codice. Ho una classe generica che ha un metodo che restituisce un intero. Ecco una versione semplice ai fini di spiegare ...Come creare un Expression.Lambda quando un tipo non è noto fino al runtime?
public class Gen<T>
{
public int DoSomething(T instance)
{
// Real code does something more interesting!
return 1;
}
}
In fase di esecuzione che utilizzare la reflection per scoprire il tipo di qualcosa e poi si desidera creare un'istanza della mia classe Gen per quella specifica tipologia. Questo è abbastanza facile e fatto come questo ...
Type fieldType = // This is the type I have discovered
Type genericType = typeof(Gen<>).MakeGenericType(fieldType);
object genericInstance = Activator.CreateInstance(genericType);
Ora voglio creare un'espressione che avrà come parametro un'istanza del tipo generico e quindi chiama il metodo DoSomething di quel tipo. Quindi voglio l'espressione di svolgere efficacemente questo ...
int answer = genericInstance.DoSomething(instance);
... tranne che non ho il 'caso' fino a un certo punto, poi in fase di esecuzione e la genericInstance è il tipo generato come si può vedere sopra. Il mio tentativo di creare la Lambda per questo è la seguente ...
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();
... in modo che in seguito posso chiamare con qualcosa di simile ...
int answer = x(genericInstance, instance);
Naturalmente, non può fornire Func con i parametri di istanza e quindi non ho idea di come parametrizzare la generazione Lambda. Qualche idea?
Una buona idea che funziona davvero. Sfortunatamente, la ragione per cui voglio usare un Lambda compilato fortemente tipizzato è la performance. L'uso di DynamicInvoke è lento rispetto a un Lambda tipizzato. –
È possibile acquisire variabili in un albero di espressioni? Aiuterei a catturare l'istanza generica in quanto non cambierà mai. –
@PhilWright Hm, vedo. Fammi vedere cos'altro posso inventare. – vcsjones