委托如何知道在有多个订阅者的情况下调用哪个函数?
本文关键字:情况下 调用 函数 何知道 | 更新日期: 2023-09-27 17:50:18
假设我有一个委托
public delegate void StringLogging(string msg);
现在类A使用这个委托来提供它自己的实现,Class B
也提供它自己的实现。StringLogging
委托的调用列表包含两个相同的方法,即一个用于Class A
,一个用于类b。委托如何知道哪个函数属于类a,哪个函数属于类b。
这在c#中是小心隐藏的。但是委托构造函数接受两个参数,一个对象和一个方法组引用。在c++/CLI语言中更容易看到,它没有相同的语法糖。例如,为按钮订阅Click事件如下所示:
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
注意第一个参数,它是实现button1_Click方法的对象的对象引用。委托类型不会对那个对象引用做任何特别的事情,它只是存储它。底层字段是Delegate.Target。稍后,当调用委托时,使用它来生成实例方法所需的同样隐藏的this引用。
c#语言不允许使用相同的语法,编译器从你传递给构造函数的方法组引用中推断出对象引用。这可以防止事故。请注意这种语法糖的代价,c#程序员通常没有意识到订阅事件会保留对目标对象的引用。导致难以诊断的泄漏是常见的事故。
c++/CLI中的显式语法允许c#中完全没有的特性,它支持未绑定委托。它不是特别有用,但它确实模拟了c++中方法指针的工作方式。c++/CLI没有采用c#糖的可能原因
内部委托实现为MultiCastDelegate
。
Delegate.GetInvocationList()
返回Delegate[]
,对应于与主Delegate
相关联的每个方法。
Delegate.Method
是有DeclaringType
的MethodInfo
。这个DeclaringType
包含了类是Class A
还是Class B
或其他类型的信息。