C# · 12月 28, 2021

c# – 运算符’==’不能应用于T类型

我以为这个方法是有效的,但我错了: static void Equals<T>(T x,T y){ return x == y; //operator == can’t be applied to type T}

阅读规范(v3.0中的§2.2.4和v4.0中的§7.3.4):

7.2.4 Binary operator overload resolution

An operation of the form x
op y,where op is an overloadable
binary operator,x is an expression of
type X,and y is an expression of type
Y,is processed as follows:

The set of candidate user-defined operators
provided by X and Y for the operation
operator op(x,y) is determined. The
set consists of the union of the
candidate operators provided by X and
the candidate operators provided by Y,
each determined using the rules of
§7.2.5. If X and Y are the same type,
or if X and Y are derived from a
common base type,then shared
candidate operators only occur in the
combined set once.

If the set of
candidate user-defined operators is
not empty,then this becomes the set
of candidate operators for the
operation. Otherwise,the predefined
binary operator op implementations,
including their lifted forms,become
the set of candidate operators for the
operation. The predefined
implementations of a given operator
are specified in the description of
the operator (§7.7 through §7.11).

The overload resolution rules of §7.4.3 are applied to the set of candidate operators to select the best operator with respect to the argument list (x,y),and this operator becomes the result of the overload resolution process. If overload resolution fails to select a single best operator,a compile-time error occurs.

在第2步中,我认为应该应用这个预定义的实现:

bool operator ==(object x,object y);bool operator !=(object x,object y);

因为C#中的所有内容都来自Object.如何在步骤3中发生编译时错误?在这种情况下,我认为“重载分辨率无法选择”是不可能的.

编辑当我实现这样的事情时,我的脑海里出现了这个问题:

class EnumComparer<TEnum> : IEqualityComparer<TEnum>{ public bool Equals(TEnum x,TEnum y) { return x == y; } public int GetHashCode(TEnum obj) { return (int)obj; }}

恐怕我需要建立一个表达式,并以Equals方法动态调用它.

解决方法 对于阅读规格很有帮助,但是你也停止阅读.如果你进一步阅读,你会得到这一点:

The predefined reference type equality operators require one of the following:

Both operands are a value of a type kNown to be a reference-type or the literal null. Furthermore,an explicit reference conversion exists from the type of either operand to the type of the other operand.

One operand is a value of type T where T is a type-parameter and the other operand is the literal null. Furthermore T does not have the value type constraint.

Unless one of these conditions are true,a binding-time error occurs. (*)

错误不是来自重载分辨率;错误是重载分辨率将选择预定义的引用类型等式运算符,并且没有引用类型.

考虑你的代码什么阻止T成为没有定义相等运算符的值类型?没有.假设我们回到对象版本;两个操作数将被包装到不同的位置,因此即使它们具有相同的内容也是不相等的.既然这是缓慢,混乱和错误的,甚至是非法的.

你为什么要这样做呢?如果你的方法工作,它不是,那么你的方法将比简单地使用==的第一个更糟糕.用这种方法你打算添加到世界的价值是多少?

(*)我把这句话中的语法错误报告给了规范维护者.