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

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

阅读指定后(v3.0中的第7.2.4节和第7.3.4节中的第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实施(包括其提升表格)成为该操作的候选操作员的集合。在操作员的描述中指定了给定操作员的预定义实现(第7.7至§7.11)。

  • 第7.4.3节的过载分辨率规则应用于候选操作员集,以选择有关参数列表(x,y)的最佳操作员,并且该操作员成为过载分辨率流程的结果。如果过载分辨率未能选择单个最佳操作员,则会发生编译时错误。

在步骤2中,我认为应该应用此预定义的实现:

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

由于C#中的所有内容都来自对象。在步骤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 方法。

有帮助吗?

解决方案

对您阅读规格有好处,但您停止阅读太早。如果您进一步阅读,您将会得到这一点:


预定义的参考类型平等操作员需要以下一个:

  • 这两个操作数都是已知的参考类型或文字零的类型的值。此外,从任何操作数的类型到其他操作数的类型都存在明确的参考转换。

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

除非这些条件之一是正确的,否则会发生绑定时间误差。 (*)


该错误不是来自过载分辨率的错误;错误是超载分辨率会选择预定义的参考类型等效操作员,并且您没有参考类型。

考虑您的代码。是什么阻止t是一个值类型,而没有相等性运算符?没有什么。假设我们回到了对象版本。这两个操作数都将盒子到不同的位置,因此即使具有相同的内容,也可以是参考线。由于那是缓慢的,令人困惑和错误的,因此即使尝试都是非法的。

您为什么首先要做这件事?如果您的方法起作用,那是不行的,那么您的方法将是 更差 首先简单地使用==。您打算用这种方法添加到世界的价值是多少?


(*)我已经将此句子中的语法错误报告给了规格维护者。

其他提示

如果知道 where T : class, ,进行参考比较。操作员通常对仿制药几乎没有支持,但是有解决方法。 Miscutil提供 间接支持操作员 关于仿制药,否则 EqualityComparer<T>.Default.Equals(x,y) 是一个不错的选择。

我喜欢使用 EqualityComparer<T>.Default 为了这。

它是基于覆盖的 Equals 方法,但使用 IEquatable<T> 如果有的话,请避免实现价值类型的拳击。

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

利用 .Equals() 方法,请确保 T 实施 IComparable

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top