我想知道是否使用Generic Constraint(何时)可以允许此代码?
这样做的正确模式是什么?
public MyClass<T>
{
public void MyMethod(T a, T b)
{
//some code
var result = a<b;
//some code
}
}
我的问题是针对所有运营商
+, -, !, ~, ++, --, *, /, %, &, |, ^, <<, >>, ==, !=, <, >, <=, >=
答案 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功能,只是因为丰富的类型推理系统才有可能。