c#泛型中的操作符

本文关键字:操作符 泛型 | 更新日期: 2023-09-27 17:49:32

在c++中我们可以这样写:

template <typename T>
    void Print(T a, T b) 
      {
          cout<<a+b<<endl;
      }
Print(12,56) or Print('c','s');
如果重载用户定义类型(类)的操作符,还可以这样写:
Person a, b; Print(a,b);

,但是在c#中我们不能写像+ -或*/这样的操作符为什么我们不能写这个?我们如何做到这一点(在泛型方法中使用操作符)?

c#泛型中的操作符

如何做到这一点(在泛型方法中使用操作符)

通常,我们不能。对于大多数操作符,如果与类型参数(如T)一起使用,编译器无法在编译时计算出适用的重载。

如果您在基类(即在非密封的引用类型上)上编写用户定义的操作符,则可以在有约束的情况下使用它们。例如,System.Uri是重载==操作符的非密封类。如果你这样做了:

class Test<T> where T : Uri
{
  internal void Method(T x, T y)
  {
    bool ok = x == y;
  }
}
使用了

用户定义的重载。当然,其他操作符也一样。

但是通常您希望使用预定义的值类型和预定义的操作符来执行此操作,例如T是一些数字类型(struct),并且您希望==(相等)或*(乘法)或<<(整数上的位移位)或类似的。但这在c#中是不可能的。

可以使用dynamic而不是泛型类型,但显然这是完全不同的。

迄今为止我发现的最佳解决方案是在MiscUtils库中。它使用表达式树在运行时执行操作。它很好,性能也很好。

不是使用operator+,而是调用Operator.Add。如果这两种类型公开一个允许操作的operator+,则调用将成功。并按预期工作。

这是c#泛型实现(以及CLR)的一个不幸的限制。更类似于c++模板的东西有时会非常有用。

为什么我们不能写这个?

因为这是语言规范所规定的。

以及如何做到这一点(在泛型方法中使用操作符)?

我们不能。

c#的局限性。

基本原因——难以猜测,离题(基于推测),但不支持操作符。时期。