C# 使用比较运算符,例如'=';和'==';,将泛型约束为C中的值#
我有以下代码:C# 使用比较运算符,例如'=';和'==';,将泛型约束为C中的值#,c#,generics,constraints,value-type,C#,Generics,Constraints,Value Type,我有以下代码: class Foo<T> where T : struct { private T t; [...] public bool Equals(T t) { return this.t == t; } } 类Foo,其中T:struct { 私人T; [...] 公共bool等于(T){返回this.T==T;} } 当我尝试编译时,会出现以下错误: 运算符“==”不能应用于“T”和“T”类型的操作数 为什么不能做到呢?如果约束是where T
class Foo<T> where T : struct
{
private T t;
[...]
public bool Equals(T t) { return this.t == t; }
}
类Foo,其中T:struct
{
私人T;
[...]
公共bool等于(T){返回this.T==T;}
}
当我尝试编译时,会出现以下错误:
运算符“==”不能应用于“T”和“T”类型的操作数
为什么不能做到呢?如果约束是where T:class
,它就可以工作了。但我需要它是值类型,因为在我的实现中,这个泛型将始终是一个枚举
我正在使用
Object.Equals()
方法来改变这种情况。因为我只是在比较T和T,所以它是否能确保始终正确的行为?这是约束系统的一个不受欢迎的限制。除非在接口中定义了值类型,否则不能根据其上的特定操作约束值类型。因此,您不能约束运算符定义,因为它们不会在所有值类型上定义,并且struct
约束允许传入任何值类型
struct A { }
它没有定义==
,但您的约束表示您愿意接受它。因此,您不能使用==
引用类型不同的原因是它们总是有可用的==
定义(标识比较)
enum
上的==
的实现与Equals
的实现非常接近,因此您的解决方法很好
与使用数字类型的
的情况进行比较!那里没有这样的解决办法。标准编号与GreaterThan
等方法没有接口。请看Jon Skeet和Marc Gravell的文章。它描述了使用Linq表达式实现“泛型运算符”。实际的实现可以在中找到,在我的时区这里有点晚了。明天我会核对其他答案,并在被接受的答案上做标记。谢谢大家!请记住,您可以使用ReferenceEquals
检查引用是否相等,这是=
通常会做的事情(除非我弄错了或者它被重写)。@Svish-ReferenceEquals
在传递值类型时总是返回false
,这就是T
被限制在这里的地方。@Earwicker:哦,对了。。。facepalm:pIt是一篇很好的文章,但如果仅仅比较相等性,肯定会有过之而无不及。NET framework已经为此提供了一个通用的方法名,Equals
,因此它可以用于所有类型。因此OP的解决方法很好,并且保证也适用于任何其他类型的参数。对于更多与数字相关的运算符,Linq表达式方法非常聪明,但它确实引入了类型洞。嗯,我明白了。。。感谢所有的澄清!在引用类型注释中,请记住,==
不能被重写,但可以重载。因此,只有当操作符用于静态已知的从该类型派生的参数时,才会调用特定引用类型上的==
定义。在泛型方法上只有一个类
约束,这意味着=
始终是身份比较。@kvb-你是对的,我删除了“除非重写”这个词,因为它在这里措词不当,而且与此无关。你关于
的最后一节完全正确。但是您可以做的是约束其中T:struct,IComparable
,然后使用CompareTo
。但是,如果类型双精度和浮点的操作数为NaN
,则CompareTo
的行为肯定不同于
。