2011-08-18 64 views
1

我明白一个动作只是一个预先声明的委托,它可以接受定义类型的单个参数。因此Action<String>表示一个没有返回并接受单个字符串参数的方法。到现在为止还挺好。代理继承说明

在我的代码,我有这样的方法:

public void Send<TMessageType>(Types.MessageBase<TMessageType> message) 
     { 
      Console.WriteLine("Message Sent"); 
      List<Delegate> subscriptions; 
      if (register.TryGetValue(typeof(TMessageType), out subscriptions)) 
      { 
       foreach (Delegate subscription in subscriptions) 
       { 
        Console.WriteLine("Invoking...."); 
        subscription.DynamicInvoke(message); 
       } 
      } 
     } 

全体代表的订阅变量实际上实例化为行动。我的问题是,为什么我的代码工作?为什么我不需要将我的委托重新投入动作(这将是Action<TMessageType>),然后我才能使用它?当然,默认的委托类型不知道需要什么参数?

回答

1

那么简短的回答是因为你的电话DynamicInvoke是一个迟到的呼叫,并且实际上并不知道它是否需要参数

MSDN

动态调用(后期绑定)的由电流代表表示方法。

补充说明:
既然你有被传递到该类型的知识Action你应该重构你的代码直接调用行为,而不能使用DynamicInvoke如果你能避免它会有性能影响。如果由于未显示的限制而无法避免它,那就这样吧。

 List<Action<Types.MessageBase<TMessageType>>> subscriptions; 
     if (register.TryGetValue(typeof(TMessageType), out subscriptions)) 
     { 
      foreach (var subscription in subscriptions) 
      { 
       Console.WriteLine("Invoking...."); 
       subscription(message); 
      } 
     } 

当然,我不知道什么会在重构的TryGetValue电话参与。

1

不,它不知道也不在乎 - 它需要一堆“对象”参数并调用你的动作。它不在编译时检查,但在运行时检查 - see here for details

1

您使用的是DynamicInvoke,顾名思义,它会动态调用委托。这比Invoke慢了一个数量级,但能够在运行时自动匹配参数类型,而不是依赖编译时间信息。