是否可以将Generic Constraint与运算符重载相结合?

时间:2018-05-20 10:00:55

标签: c# generics operator-overloading generic-constraints

我想知道是否使用Generic Constraint(何时)可以允许此代码?

这样做的正确模式是什么?

public MyClass<T>
{
    public void MyMethod(T a, T b) 
    {
       //some code
       var result = a<b;
      //some code 
    }
}

我的问题是针对所有运营商

+, -, !, ~, ++, --, *, /, %, &, |, ^, <<, >>, ==, !=, <, >, <=, >=

2 个答案:

答案 0 :(得分:2)

此时(2018年5月),您唯一能做的就是向IComparable<T>添加一个约束到类定义并使用CompareTo方法而不是<

public class MyClass<T> where T : IComparable<T>
{
    public void MyMethod(T a, T b) 
    {
       //some code
       var result = a.CompareTo(b) < 0; // a < b
       //some code 
    }
}

这将涵盖<<=>>=(技术上甚至是==,但最好使用IEquatable<T> }),对于==,您可以向类IEquatable<T>添加约束到类定义,并使用Equals方法而不是==(以及!Equals而不是!=)。

对于此时的数学/位运算符,没有希望。 C#wishlist中始终要求使用此功能,但它们总是被推迟。在C#8.0中,此功能将不存在(可能)。请参阅official list of candidates。有关此问题,请参阅Generic C# Code and the Plus Operator。请注意,如果您尝试使用不存在的运算符,则在编译时给出的解决方案不会出错,但会在运行时给出这些错误。

答案 1 :(得分:1)

这实际上与模式匹配无关。 where(不是when)在这种情况下意味着generic constraints。 并且不可能对运营商有约束。

您可能希望使用自定义界面,在其上添加约束。

public class MyClass<T> where T: ICustomInterface

IComparable>运算符的一个很好的候选者,但它不适合您希望运算符重载。

顺便说一句,F#允许你使用Member constraints这样的约束 - 它被称为Statically resolved type parameters。它允许您在任何类型成员或运算符上添加约束。但这不是CLR功能,只是因为丰富的类型推理系统才有可能。