簡體   English   中英

C#:通過反射將通用組播委托分配給具有不同數量參數的操作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM