[英]C# : Assign generic Multicast-Delegate to Action with different amount of parameters via reflection
所以在我的 class 中有一些代表都是 Action<...> 字段。 例子:
public Action<int> onDiceRolled;
public Action<Turn, Round> onTurnEnded;
我想使用反射為他們每個人分配一個匿名的 function 。
GetType().GetFields()
.Where(field => field.FieldType.ToString().Contains("Action"))
.ToList()
.ForEach(field =>
{
Type type = field.FieldType; // e.g. Action<Turn, Round>
if (!type.IsGenericType)
return;
Type[] para = type.GetGenericArguments(); // in example cases: {int} or {Turn, Round}
MethodInfo debugMethod = (new Action(() => Console.WriteLine(field.Name + " was called."))).Method;
field.SetValue(this, Delegate.CreateDelegate(type, debugMethod));
});
當然這不起作用,因為創建的委托沒有任何參數,而它需要的參數存儲在 para. 不幸的是,我找不到通過類型數組創建委托的任何方法。
所以基本上我想做
onDiceRolled += (i) => Console.WriteLine("onDiceRolled was called.");
對於我的 class 中的每個操作字段
要設置委托,您可以使用表達式樹來編譯一個:
GetType().GetFields()
.Where(field => field.FieldType.ToString().Contains("Action"))
.ToList()
.ForEach(field =>
{
Type type = field.FieldType; // e.g. Action<Turn, Round>
if (!type.IsGenericType)
return;
Type[] para = type.GetGenericArguments(); // in example cases: {int} or {Turn, Round}
Expression<Action> x = () => Console.WriteLine(field.Name + " was called.");
var action = Expression.Lambda(x.Body, para.Select(p => Expression.Parameter(p))).Compile();
field.SetValue(this, action);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.