3

这个问题来自之前关于 C++ Functors 的讨论(Do functors have an equivalent in C#?)。

为什么 C# 不允许重载 operator()?

您可以重载运算符,但如果 operator() 也可以重载,会有什么好处呢?

4

1 回答 1

2

C# has operator(),它拼写为Invoke.

任何时候定义delegate类型时,您都在定义一个具有命名方法的类,Invoke并且可以对该类的实例使用函数调用语法,这将导致调用Invoke. 就像operator(),C# 委托Invoke方法几乎可以有任何函数签名。

与 C++ 不同operator(),C# 不允许在定义Invoke. 你可以说 C# 在这里执行单一职责原则。但是,这不是主要限制,因为 C# 委托被连接到另一个对象,该对象为函数对象提供状态存储。

Invoke与 C++ 相比,C# 的一个更严重的(在没有简单解决方法的意义上)限制operator()是 C# 委托Invoke方法不能被重载或多态。这是需要将调用转发到另一个对象上的方法的结果,但它阻止了 C++ 自定义函子可能出现的一些使用场景。

如果您Invoke使用 MSIL 定义重载方法,看看会发生什么会很有趣。如果您尝试使用这样的委托类,当然您会混淆 C# 编译器,并且可能还会混淆 CLR 运行时。所以这是一种奇思妙想,而不是一种实用的方法。

C++std::function在功能和限制方面与 C# 委托类型非常相似。它还转发调用,并且在调用签名上不是多态的。同样适用于 C++11 lambda,尽管 C++14 lambda 将允许模板化operator()和调用站点类型多态(与仅允许定义点多态的 C# lambda 不同)。

于 2013-06-17T13:20:29.810 回答