我理解一个动作只是一个预先声明的委托,它可以接受所定义类型的单个参数。所以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);
}
}
}
subscriptions变量中的所有Delegates实际上都被实例化为actions。我的问题是,为什么我的代码有效?为什么我不需要在我可以使用它之前将我的委托重新投入一个动作(它将是Action<TMessageType>
)?当然默认的委托类型不知道期望什么参数?
答案 0 :(得分: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 :(得分:1)
不,它不知道也不关心 - 它需要一堆“对象”参数并用它来调用你的动作。它不会在编译时检查,而是在运行时检查 - see here for details
答案 2 :(得分:1)
您正在使用DynamicInvoke
,顾名思义,它会动态调用委托。它比Invoke
慢一个数量级,但能够在运行时自动匹配参数类型,而不是依赖于编译时信息。