0

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

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

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

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

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

2 回答 2

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# 愿望清单中总是有对此功能的请求,但它们总是被推迟。在 C# 8.0 中,此功能将不存在(可能)。见官方候选人名单。有关此问题,请参阅通用 C# 代码和加号运算符。请注意,如果您尝试使用不存在的运算符,给出的解决方案不会在编译时出错,但会在运行时出错。

于 2018-05-20T10:42:10.530 回答
1

这实际上与模式匹配无关。where(不是when)在这种情况下意味着通用约束。不,不可能对运算符进行约束。

您可能想改用自定义界面,在其上添加约束。

public class MyClass<T> where T: ICustomInterface

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

顺便说一句,F# 允许您使用静态解析的类型参数来拥有这样的约束——它被称为成员约束。它允许您对任何类型成员或运算符添加约束。但这不是 CLR 的特性,这可能只是因为丰富的类型推理系统。

于 2018-05-20T10:30:46.960 回答