说我有代表
public delegate void StringLogging(string msg);
现在,A类使用此委托提供自己的实现,Class B
也提供了自己的实现。 StringLogging
委托的调用列表包含两个相同的方法,即一个用于Class A
,一个用于类B.委托如何知道哪个函数属于A类,哪个属于B类。
答案 0 :(得分:4)
内部Delegates实施为MultiCastDelegate
。
Delegate.GetInvocationList()
会返回Delegate[]
,这些Delegate
对应于与主DeclaringType
相关联的每种方法。
Delegate.Method
MethodInfo
为DeclaringType
。此Class A
包含类是Class B
还是{{1}}还是其他类型的信息。
答案 1 :(得分:4)
这是在C#中小心隐藏的。但委托构造函数采用两个参数,一个对象和一个方法组引用。在C ++ / CLI语言中更容易看到,它没有相同的语法糖。例如,为按钮订阅Click事件如下所示:
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
注意第一个参数,即实现button1_Click方法的对象的对象引用。委托类型对该对象引用没有任何特殊处理,它只是存储它。底层字段是Delegate.Target。稍后,在调用委托时使用它来生成实例方法所需的隐藏的 this 引用。
C#语言不允许使用相同的语法,编译器从构造函数中传递的方法组引用中推断出对象引用。这可以防止意外。请注意这种语法糖的价格,C#程序员通常不会意识到订阅事件会保留对目标对象的引用。导致难以诊断的泄漏是一种常见的不幸事件。
C ++ / CLI中的显式语法允许在C#中完全缺少的功能,它支持unbound delegates。它并不是特别有用,但它确实模拟了C ++中方法指针的工作方式。可能的原因C ++ / CLI没有采用C#糖。