Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用比较运算符,例如'=';和'==';,将泛型约束为C中的值#_C#_Generics_Constraints_Value Type - Fatal编程技术网

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
的行为肯定不同于