繁体   English   中英

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

[英]Operator '==' can't be applied to type T?

我认为这种方法是有效的,但我错了:

static void Equals<T>(T x, T y)
{
    return x == y;    //operator == can't be applied to type T
}

阅读规范后(v3.0 中的第 7.2.4 节和 v4.0 中的第 7.3.4 节):

7.2.4 二元运算符重载决议

x op y 形式的运算,其中 op 是可重载的二元运算符,x 是 X 类型的表达式,y 是 Y 类型的表达式,处理如下:

  • 确定由 X 和 Y 为操作算子 op(x, y) 提供的候选用户定义算子集合。 该集合由 X 提供的候选运算符和 Y 提供的候选运算符的联合组成,每个运算符都使用第 7.2.5 节的规则确定。 如果 X 和 Y 是同一类型,或者如果 X 和 Y 派生自一个共同的基本类型,则共享候选运算符仅在组合集中出现一次。

  • 如果候选用户定义运算符的集合不为空,则这成为该操作的候选运算符集合。 否则,预定义的二元运算符 op 实现,包括其提升的 forms,将成为该运算的候选运算符集。 给定运算符的预定义实现在运算符的描述中指定(第 7.7 节到第 7.11 节)。

  • §7.4.3 的重载决策规则应用于候选运算符集,以 select 为相对于参数列表 (x, y) 的最佳运算符,该运算符成为重载决策过程的结果。 如果重载决议未能 select 单个最佳运算符,则会发生编译时错误。

在第 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方法中动态调用它。

阅读规范对您有好处,但您过早停止阅读。 如果您进一步阅读,您将了解这一点:


预定义的引用类型相等运算符需要以下之一:

  • 两个操作数都是已知为引用类型或文字 null 的类型的值。 此外,存在从任一操作数类型到另一操作数类型的显式引用转换。

  • 一个操作数是 T 类型的值,其中 T 是类型参数,另一个操作数是字面量 null。 此外,T 没有值类型约束。

除非这些条件之一为真,否则会发生绑定时错误。 (*)


错误不是来自重载解决方案; 错误是重载决议会选择预定义的引用类型相等运算符,并且您没有引用类型。

考虑你的代码。 是什么阻止了 T 成为一个没有定义相等运算符的值类型? 没有什么。 假设我们退回到 object 版本; 两个操作数都会装箱到不同的位置,因此即使它们具有相同的内容,它们也是不相等的。 由于这是缓慢、令人困惑和错误的,因此即使尝试也是非法的。

你为什么要首先尝试做这件事? 如果您的方法有效,但它没有,那么您的方法将比首先简单地使用 ==更糟糕 你打算用这种方法为世界增加什么价值?


(*) 我已经向规范维护者报告了这句话中的语法错误。

如果它知道在where T: class进行参考比较,那可能会起作用。 运营商通常对 generics 的支持很少,但有一些变通方法。 MiscUtil 为 generics 上 的运算符提供间接支持,否则EqualityComparer<T>.Default.Equals(x,y)是一个不错的选择。

我喜欢为此使用EqualityComparer<T>.Default

它基于重写的Equals方法,但在可用时使用IEquatable<T> ,避免对实现它的值类型进行装箱。

EqualityComparer<T>.Default.Equals(x, y)

使用.Equals()方法并确保T实现IComparable

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM