运算符'=='不能应用于类型T?
运算符'=='不能应用于类型T?
我原以为这个方法是有效的,但我错了:\n
static void Equals(T x, T y) { return x == y; //operator == 无法应用于类型 T }
\n在阅读规范之后(v3.0 中的 §7.2.4 和 v4.0 中的 §7.3.4):\n
\n7.2.4 二元运算符重载解析\n形如 x op y 的操作,其中 op 是可重载的二元运算符,x 是类型 X 的表达式,y 是类型 Y 的表达式,处理如下:\n
\n
- 确定 X 和 Y 提供的用于操作 operator op(x, y) 的候选用户定义运算符集。该集合由 X 提供的候选运算符和 Y 提供的候选运算符的并集组成,每个候选运算符都使用 §7.2.5 的规则确定。如果 X 和 Y 是相同类型,或者 X 和 Y 都派生自公共基类型,则共享的候选运算符只出现一次在组合的集合中。
\n
- 如果候选用户定义运算符集不为空,则这成为操作的候选运算符集。否则,预定义的二元运算符 op 实现,包括其提升形式,成为操作的候选运算符集。给定运算符的预定义实现在运算符的描述中指定(§7.7 到 §7.11)。
\n
- 将 §7.4.3 的重载解析规则应用于候选运算符集,以选择与参数列表(x,y)最佳匹配的运算符,并将该运算符成为重载解析过程的结果。如果重载解析无法选择单个最佳运算符,则会发生编译时错误。
\n
\n
\n在第二步中,我认为应该应用这个预定义实现:\n
bool operator ==(object x, object y); bool operator !=(object x, object y);
\n因为 C# 中的所有内容都派生自 Object。在第三步中,为什么会发生编译时错误?我认为在这种情况下“重载解析无法选择”是不可能的。\n编辑 当我实现以下内容时,这个问题浮现在我的脑海中:\n
class EnumComparer: IEqualityComparer { public bool Equals(TEnum x, TEnum y) { return x == y; } public int GetHashCode(TEnum obj) { return (int)obj; } }
\n我担心我需要在 Equals
方法中构建一个表达式并动态调用它。
问题:Operator '==' can't be applied to type T?
原因:出现这个问题的原因是在使用'=='操作符比较两个泛型类型T的对象时,编译器无法确定T类型是否支持'=='操作符的比较。
解决方法:可以使用EqualityComparer
示例代码如下:
if (EqualityComparer.Default.Equals(x, y)) { // 逻辑处理 }
通过使用EqualityComparer
Operator '==' can't be applied to type T? 这个问题的出现的原因是在泛型中,操作符'=='不支持所有类型的比较。在这个具体的问题中,泛型T可能是一个枚举类型,而枚举类型无法直接使用操作符'=='进行比较。
解决方法是使用EqualityComparer
在这个的问题中,还提到了MiscUtil库提供了对泛型操作符的间接支持。另外,如果T是实现了IEquatable
另外,还有一个相关的问题是关于EqualityComparer
总结起来,解决Operator '==' can't be applied to type T?这个问题的方法是使用EqualityComparer
问题的出现的原因是在使用==运算符进行比较时,类型T可能是一个值类型,并且未定义相等运算符。根据规范,预定义的引用类型相等运算符需要满足以下条件之一:
1. 两个操作数都是已知为引用类型或字面值null的值。而且,从任一操作数的类型到另一操作数的类型存在显式引用转换。
2. 一个操作数是类型T的值,并且另一个操作数是字面值null。此外,T没有值类型约束。
除非满足上述条件之一,否则会发生绑定时错误。问题不是来自于重载解析,而是重载解析会选择预定义的引用类型相等运算符,而你没有引用类型。
解决这个问题的方法是:
1. 如果T是一个已知为引用类型的值,可以通过显式引用转换来解决问题。
2. 如果T是一个值类型,可以先将其转换为引用类型,然后再使用==运算符进行比较。
然而,需要注意的是,为什么要尝试在第一次使用==运算符时进行这个操作?如果这种方法是有效的(实际上是无效的),那么这种方法将比直接使用==运算符更差。在编写代码时,需要考虑到是否真正需要这种方法,以及它能为世界带来什么价值。
值得注意的是,上述引用来自于一个问题,这个问题提出了一个关于EqualityComparer.Default的相关问题。