c# - 在多个订阅者的情况下,委托(delegate)如何知道调用哪个函数

标签 c# .net delegates

假设我有一个委托(delegate)

public delegate void StringLogging(string msg);

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

最佳答案

这在 C# 中被小心地隐藏了。但是委托(delegate)构造函数有两个参数,一个对象和一个方法组引用。在 C++/CLI 语言中更容易看到,它没有相同的语法糖。例如,订阅按钮的 Click 事件如下所示:

 this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);

请注意第一个参数,即实现 button1_Click 方法的对象的对象引用。委托(delegate)类型对该对象引用没有做任何特殊的事情,它只是简单地存储它。底层字段是 Delegate.Target。稍后,在调用委托(delegate)时使用它来生成实例方法所需的同样隐藏的 this 引用。

C# 语言不允许相同的语法,编译器推断对象引用来自您在构造函数中传递的方法组引用。这样可以防止事故。请注意这种语法糖的代价,C# 程序员通常不会意识到订阅事件会保留对目标对象的引用。导致难以诊断的泄漏是一种常见的事故。

C++/CLI 中的显式语法允许使用 C# 中完全缺失的功能,它支持 unbound delegates .它不是特别有用,但它确实模拟了 C++ 中方法指针的工作方式。 C++/CLI 没有采用 C# 糖的可能原因。

关于c# - 在多个订阅者的情况下,委托(delegate)如何知道调用哪个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14101995/

相关文章:

c# - 通过 .NetCore SQLConnection 到 MariaDB localhost

c# - mvc core中注册DI时如何访问ISession

c# - MigrateDatabaseToLatestVersion 没有运行 Seed() 方法

c# - 跨程序集移动的反序列化类型

vb.net - 添加一个包含所有四个数学过程的多播委托(delegate)?

c# - 通过 Func<> 传递参数

c# - 合并两个(或更多)PDF

c# - 阅读 C# 中的打开文件问题

c# - 如何制作像 Office 2010 那样的丝带

c# - 使用泛型类的参数作为事件类型