這是使用代碼最好的解釋。我有一個泛型類,它有一個返回整數的方法。下面是一個簡單的版本用於解釋的目的...如何在類型直到運行時才知道時創建Expression.Lambda?
public class Gen<T>
{
public int DoSomething(T instance)
{
// Real code does something more interesting!
return 1;
}
}
在運行時我使用反射來發現的一些類型,然後想爲特定類型的創建我的根類的一個實例。這是很容易像這樣做...
Type fieldType = // This is the type I have discovered
Type genericType = typeof(Gen<>).MakeGenericType(fieldType);
object genericInstance = Activator.CreateInstance(genericType);
我現在要創建一個將作爲一個參數的泛型類型的實例表達式,然後調用類型的DoSomething的方法。所以我想表達的有效執行此...
int answer = genericInstance.DoSomething(instance);
...除了我沒有「實例」,直到某個點以後在運行時和genericInstance是生成的類型,從上面可以看出。我在創建拉姆達這是如下的嘗試......
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();
...因此以後我可以像這樣把它...
int answer = x(genericInstance, instance);
當然,你無法爲Func提供實例參數,因此我不知道如何參數化Lambda代。有任何想法嗎?
一個確實有效的好主意。不幸的是,我想使用強類型編譯Lambda的原因是性能。與類型化的Lambda相比,使用DynamicInvoke非常慢。 –
是否可以捕獲表達式樹中的變量?我會幫助捕獲genericInstance,因爲這永遠不會改變。 –
@PhilWright嗯,我明白了。讓我看看我還能想出什麼。 – vcsjones