为什么你不能要求泛型中的运算符重载

Col*_*son 5 .net c# generics cil cil-metadata

在C++中,您可以编写如下代码:

template<class T>
T Add(T lhs, T rhs)
{
    return lhs + rhs;
}
Run Code Online (Sandbox Code Playgroud)

但是,你不能在C#中做这样的事情:

public static T Add<T>(T x, T y) where T : operator+
{
    return x + y;
}
Run Code Online (Sandbox Code Playgroud)

有什么理由吗?我知道它可以通过反射来实现(通用Add对象然后对它进行运行类型检查),但这样效率低,并且不能很好地扩展.那么,为什么呢?

usr*_*usr 5

没有固有的理由不存在这种情况.实现泛型类型约束的方式是通过接口调用.如果有一个接口提供了operator+这将工作.

但是,所有相关类型需要此接口,与基于C++模板的模拟一样通用.

另一个问题是.NET没有多个调度.接口调用将是不对称的:a.Plus(b)可能意味着不同于b.Plus(a).Equals有同样的问题,顺便说一句.

所以这个问题可能不符合"有用性"-bar或"成本/效用"-bar.这不是不可能的问题,而是实际问题.

证明有可能:((dynamic)a) + ((dynamic)b).

  • 你没有提到的一件事(至少没有明确说明):*不能*是一个提供`operator +`的接口,因为运算符必须是`static`方法而``static`方法不能是接口. (3认同)