运算符'=='不能应用于类型T?

26 浏览
0 Comments

运算符'=='不能应用于类型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 方法中构建一个表达式并动态调用它。

0
0 Comments

问题:Operator '==' can't be applied to type T?

原因:出现这个问题的原因是在使用'=='操作符比较两个泛型类型T的对象时,编译器无法确定T类型是否支持'=='操作符的比较。

解决方法:可以使用EqualityComparer.Default.Equals(x, y)方法来进行比较。这个方法是基于重写的Equals方法进行比较的,但是当可用时,它会使用IEquatable来避免值类型的装箱操作。

示例代码如下:

if (EqualityComparer.Default.Equals(x, y))
{
    // 逻辑处理
}

通过使用EqualityComparer.Default.Equals方法,我们可以在比较泛型类型T的对象时避免出现'=='操作符无法应用于类型T的问题。

0
0 Comments

Operator '==' can't be applied to type T? 这个问题的出现的原因是在泛型中,操作符'=='不支持所有类型的比较。在这个具体的问题中,泛型T可能是一个枚举类型,而枚举类型无法直接使用操作符'=='进行比较。

解决方法是使用EqualityComparer.Default.Equals(x, y)来替代操作符'=='进行比较。这个方法会根据T的类型选择合适的比较方式,避免了直接使用操作符'=='的问题。

在这个的问题中,还提到了MiscUtil库提供了对泛型操作符的间接支持。另外,如果T是实现了IEquatable接口的类型,则可以避免装箱操作。

另外,还有一个相关的问题是关于EqualityComparer.Default.Equals(x, y)的实现方式。其中一个可能的实现方式是使用操作符'=='或者x.Equals(y),但是这种方式可能会导致装箱操作。在这个的问题中,提到了通过元编程来编写一个不涉及装箱操作的实现方式。

总结起来,解决Operator '==' can't be applied to type T?这个问题的方法是使用EqualityComparer.Default.Equals(x, y)进行比较,避免直接使用操作符'=='。另外,如果T是实现了IEquatable接口的类型,则可以避免装箱操作。如果需要更高级的解决方案,可以考虑使用MiscUtil库提供的间接支持或者通过元编程来编写特定类型的比较方法。

0
0 Comments

问题的出现的原因是在使用==运算符进行比较时,类型T可能是一个值类型,并且未定义相等运算符。根据规范,预定义的引用类型相等运算符需要满足以下条件之一:

1. 两个操作数都是已知为引用类型或字面值null的值。而且,从任一操作数的类型到另一操作数的类型存在显式引用转换。

2. 一个操作数是类型T的值,并且另一个操作数是字面值null。此外,T没有值类型约束。

除非满足上述条件之一,否则会发生绑定时错误。问题不是来自于重载解析,而是重载解析会选择预定义的引用类型相等运算符,而你没有引用类型。

解决这个问题的方法是:

1. 如果T是一个已知为引用类型的值,可以通过显式引用转换来解决问题。

2. 如果T是一个值类型,可以先将其转换为引用类型,然后再使用==运算符进行比较。

然而,需要注意的是,为什么要尝试在第一次使用==运算符时进行这个操作?如果这种方法是有效的(实际上是无效的),那么这种方法将比直接使用==运算符更差。在编写代码时,需要考虑到是否真正需要这种方法,以及它能为世界带来什么价值。

值得注意的是,上述引用来自于一个问题,这个问题提出了一个关于EqualityComparer.Default的相关问题。

0