【问题标题】:C#: Default implementation for == and != operators for objectsC#:对象的 == 和 != 运算符的默认实现
【发布时间】:2011-09-08 09:36:09
【问题描述】:

我想知道相等运算符(== 和 !=)的默认实现是什么

是吗?

public static bool operator ==(object obj1, object obj2)
{
    return obj1.Equals(obj2);
}
public static bool operator !=(object obj1, object obj2)
{
    return !obj1.Equals(obj2);
}

所以我只需要重写 Equals 方法还是也需要重写 euality 运算符?

【问题讨论】:

标签: c# .net c#-4.0


【解决方案1】:

不,它是 not - 默认情况下,references 会检查是否相等。 == 等运算符是 not 多态的,默认情况下不会 调用 任何多态的东西。比如:

string x = "Hello";
string y = new String("Hello".ToCharArray());
Console.WriteLine(x == y); // True; uses overloaded operator

object a = x;
object b = y;
Console.WriteLine(a == b); // False; uses default implementation

你不能覆盖等式运算符,但你可以重载它们,就像字符串一样。你是否应该是另一回事。如果我覆盖Equals,我想我通常会这样做,但不一定总是如此。

【讨论】:

  • Eric Lippert 的 evil example: object obj = ""; string str2 = String.Empty; Console.WriteLine(obj == str2); // sometimes true, sometimes false
  • 这是一个非常好的答案,并在此过程中解释了许多其他事情。这就是它与Equal() 方法不同的地方。 Equal 方法是 virtual 方法,因此 x.Equals(y) 将返回 true,因为它将在运行时绑定,并且运行时等效于该方法是 strings Equal 方法。但是==不能被覆盖,只能覆盖overloaded,并且在编译时会确定调用哪个运算符,并使用参数类型来确定要绑定到哪个重载。谢谢@JonSkeet。
  • 虽然这个例子是对的,但解释是错误的。最初的问题与多态性、重载或覆盖无关。 == 的默认实现调用 ReferenceEquals() 而不是 Equals()。
  • @Trade-IdeasPhilip:当原始问题问:“所以我只需要覆盖 Equals 方法”时,原始问题与覆盖无关?不,== 不会调用 ReferenceEquals - 恰恰相反。
  • 他问是默认实现... obj1.Equals(obj2) ...?答案是否定的,默认实现是 ... obj1.ReferenceEquals(obj2) ... 或非常接近的东西。这就是为什么覆盖 Equals() 是不够的。
【解决方案2】:

C# language specification,第 7.9 节涵盖了内置 == 运算符的确切行为。例如,在引用类型值上使用 == 时,以下部分适用:

7.9.6 引用类型相等运算符

预定义的引用类型相等运算符有:

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

运算符返回比较两个引用是否相等的结果。

由于预定义的引用类型相等运算符接受 object 类型的操作数,它们适用于所有未声明适用 operator == 和 operator != 成员的类型。相反,任何适用的用户定义相等运算符都有效地隐藏了预定义的引用类型相等运算符。

[更多细节跳过...]

请注意,“比较两个引用是否相等”并不意味着“调用obj1.Equals(obj2)的结果”。这意味着两个引用必须指向同一个对象(引用相等)。

【讨论】:

  • 值得注意的是,== 的现有规范和引用相等性存在问题。这是一个非常棘手的问题 - 我们希望我们已经在 ECMA 规范的下一个版本中修复了它。
  • @JonSkeet:听起来很有趣。有详细链接吗?
  • 不,恐怕不会。所有的讨论都是私人的,至少目前是这样。 (而且很多都是亲自发生的。)隐式转换最终会出现问题,IIRC ...
【解决方案3】:

默认情况下,这些运算符会测试 reference 的相等性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    • 2014-01-22
    • 2021-05-11
    相关资源
    最近更新 更多