委托如何知道在有多个订阅者的情况下调用哪个函数?

本文关键字:情况下 调用 函数 何知道 | 更新日期: 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是有DeclaringTypeMethodInfo。这个DeclaringType包含了类是Class A还是Class B或其他类型的信息。