2011-08-18 54 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慢了一個數量級,但能夠在運行時自動匹配參數類型,而不是依賴編譯時間信息。