如果有多个订阅者,代理如何知道要调用哪个函数

时间:2012-12-31 13:05:58

标签: c# .net delegates

说我有代表

public delegate void StringLogging(string msg);

现在,A类使用此委托提供自己的实现,Class B也提供了自己的实现。 StringLogging委托的调用列表包含两个相同的方法,即一个用于Class A,一个用于类B.委托如何知道哪个函数属于A类,哪个属于B类。

2 个答案:

答案 0 :(得分:4)

内部Delegates实施为MultiCastDelegate

Delegate.GetInvocationList()会返回Delegate[],这些Delegate对应于与主DeclaringType相关联的每种方法。

Delegate.Method MethodInfoDeclaringType。此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#糖。