==与.NET中的Object.Equals(对象)

时间:2022-03-27 16:17:44

So, when I was a comparative novice to the novice I am right now, I used to think that these two things were syntactic sugar for each other, i.e. that using one over the other was simply a personal preference. Over time, I'm come to find that these two are not the same thing, even in a default implementation (see this and this). To further confuse the matter, each can be overridden/overloaded separately to have completely different meanings.

因此,当我现在是新手的比较新手时,我曾经认为这两件事情是彼此的语法糖,即使用一个而不是另一个只是个人偏好。随着时间的推移,我发现即使在默认实现中,这两者也不是一回事(参见本章和本章)。为了进一步混淆这个问题,每个都可以单独覆盖/重载,以具有完全不同的含义。

Is this a good thing, what are the differences, and when/why should you use one over the other?

这是一件好事,有什么不同之处,以及何时/为什么要使用一个而不是另一个?

8 个解决方案

#1


17  

MSDN has clear and solid descriptions of both things.

MSDN对这两个方面都有清晰而可靠的描述。

object.Equals method

object.Equals方法

operator ==

operator ==

Overloadable Operators

可重载运算符

Guidelines for Overriding Equals() and Operator ==

覆盖等于()和运算符的指南==

Is this a good thing, what are the differences, and when/why should you use one over the other?

这是一件好事,有什么不同之处,何时/为什么要使用其中一个?

How can it be "good" or "bad" thing? One - method, another - operator. If reference equality is not sufficient, overload them, otherwise leave them as is. For primitive types they just work out of box.

它怎么可能是“好”或“坏”的东西?一种方法,另一种方法 - 操作者。如果引用相等是不够的,请将它们重载,否则保持原样。对于原始类型,它们只能在盒子外工作。

#2


33  

string x = "hello";
string y = String.Copy(x);
string z = "hello";

To test if x points to the same object as y:

要测试x是否指向与y相同的对象:

(object)x == (object)y  // false
x.ReferenceEquals(y)    // false
x.ReferenceEquals(z)    // true (because x and z are both constants they
                        //       will point to the same location in memory)

To test if x has the same string value as y:

要测试x是否与y具有相同的字符串值:

x == y        // true
x == z        // true
x.Equals(y)   // true
y == "hello"  // true

Note that this is different to Java. In Java the == operator is not overloaded so a common mistake in Java is:

请注意,这与Java不同。在Java中,==运算符没有重载,因此Java中常见的错误是:

y == "hello"  // false (y is not the same object as "hello")

For string comparison in Java you need to always use .equals()

对于Java中的字符串比较,您需要始终使用.equals()

y.equals("hello")  // true

#3


9  

Given Microsoft's current statement on equality operators == and !=, the conclusion is: == should just be syntactic sugar for Object.Equals():

鉴于微软目前关于等式运算符的陈述==和!=,结论是:==应该只是Object.Equals()的语法糖:

DO ensure that Object.Equals and the equality operators have exactly the same semantics

确保Object.Equals和相等运算符具有完全相同的语义

from http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx

来自http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx

That they are distinct, rather than just sugar, in hindsight, appears to be a mistake in their design.

事后看来,他们是独特的,而不仅仅是糖,在他们的设计中似乎是一个错误。

If you want to be certain you are getting IDENTITY comparison (when comparing references), then use ReferenceEquals instead.

如果您想确定您正在进行IDENTITY比较(比较参考时),请改用ReferenceEquals。

Unfortunately, the handling of == is so inconsistent, that I usually avoid it when manipulating someone else's custom classes, and just use the less readable Equals(a, b) or ReferenceEquals(a, b), depending on which meaning I want.

不幸的是,==的处理是如此不一致,我通常在操纵别人的自定义类时避免使用它,而只是使用不太可读的Equals(a,b)或ReferenceEquals(a,b),这取决于我想要的含义。

IMHO, it would be better for people to not implement == and != at all. Just let .Net default to Equals and ! Equals, and implement Equals as appropriate.

恕我直言,人们最好不要实现==和!=。只需将.Net默认为等于和!等于,并在适当时实施Equals。

If anyone has different reasoning, I'd like to hear it.

如果有人有不同的推理,我想听听。

(And yes, this is really confusing, given that Java existed first, and uses == to mean ReferenceEquals. But it is too late to alter .Net to behave that way. And we have Microsoft's own statement to that effect, in the link given above.)

(是的,这确实令人困惑,因为Java首先存在,并使用==来表示ReferenceEquals。但是改变.Net以这种方式行为为时已晚。而且我们有微软自己的声明,在链接中如上所述。)

#4


4  

I was going to post this as a comment on the accepted answer, but I think this deserves to be considered when determining which route to take.

我打算将此作为对已接受答案的评论发布,但我认为在确定采用哪条路线时应该考虑这一点。

dotnetfiddle: https://dotnetfiddle.net/gESLzO

dotnetfiddle:https://dotnetfiddle.net/gESLzO

Fiddle code:

小提琴代码:

    Object a = null;
    Object b = new Object();

    // Ex 1
    Console.WriteLine(a == b);
    // Ex 2
    Console.WriteLine(b == a);

    // Ex 3     
    Console.WriteLine(b.Equals(a));
    // Ex 4
    Console.WriteLine(a.Equals(b));

The first 3 WriteLine examples will work, but the fourth throws an exception. 1 and 2 use ==, which is a static method that does not require either object to be instantiated.

前3个WriteLine示例将起作用,但第四个抛出异常。 1和2使用==,这是一个静态方法,不需要实例化任何对象。

Example 3 works because b is instantiated.

示例3起作用,因为b被实例化。

Example 4 fails because a is null, and thus a method can not be called on a null object.

示例4失败,因为a为null,因此无法在null对象上调用方法。

Because I try to code as lazily as possible, I use ==, especially when working with scenarios where either object (or both) can be null. If I didn't, I'd have to do a null check, first, before being able to call .Equals().

因为我尝试尽可能懒惰地编码,所以我使用==,尤其是在使用其中任一对象(或两者)都可以为null的场景时。如果我没有,我必须首先进行空检查,然后才能调用.Equals()。

#5


1  

My understanding of the uses of both was this: use == for conceptual equality (in context, do these two arguments mean the same thing?), and .Equals for concrete equality (are these two arguments in actual fact the exact same object?).

我对两者用法的理解是这样的:使用==进行概念上的相等(在上下文中,这两个参数是否意味着相同的东西?),和.Equals用于具体的相等(实际上这两个参数是完全相同的对象吗? )。

Edit: Kevin Sheffield's linked article does a better job of explaining value vs. reference equality…

编辑:凯文谢菲尔德的链接文章在解释价值与参考平等方面做得更好......

#6


0  

You may want to use .Equals as someone may come along at a later time and overload them for you class.

你可能想要使用.Equals,因为有些人可能会在以后出现并为你上课超载。

#7


-1  

Two of the most often used types, String and Int32, implement both operator==() and Equals() as value equality (instead of reference equality). I think one can consider these two defining examples, so my conclusion is that both have identical meanings. If Microsoft states otherwise, I think they are intentionally causing confusion.

两种最常用的类型String和Int32将operator ==()和Equals()实现为值相等(而不是引用相等)。我认为可以考虑这两个定义的例子,所以我的结论是两者都有相同的含义。如果微软另有说明,我认为他们故意造成混淆。

#8


-1  

Operator == and Equals() both are same while we are comparing values instead of references. Output of both are same see below example.

当我们比较值而不是引用时,运算符==和等于()都是相同的。两者的输出相同,见下面的例子。

Example

    static void Main()
    {
        string x = " hello";
        string y = " hello";
        string z = string.Copy(x);
        if (x == y)
        {
            Console.WriteLine("== Operator");
        }
        if(x.Equals(y))
        {
            Console.WriteLine("Equals() Function Call");
        }
        if (x == z)
        {
            Console.WriteLine("== Operator while coping a string to another.");
        }
        if (x.Equals(y))
        {
            Console.WriteLine("Equals() Function Call while coping a string to another.");
        }
    }

Output:

输出:

  == Operator
  Equals() Function Call
  == Operator while coping a string to another.
  Equals() Function Call while coping a string to another.

#1


17  

MSDN has clear and solid descriptions of both things.

MSDN对这两个方面都有清晰而可靠的描述。

object.Equals method

object.Equals方法

operator ==

operator ==

Overloadable Operators

可重载运算符

Guidelines for Overriding Equals() and Operator ==

覆盖等于()和运算符的指南==

Is this a good thing, what are the differences, and when/why should you use one over the other?

这是一件好事,有什么不同之处,何时/为什么要使用其中一个?

How can it be "good" or "bad" thing? One - method, another - operator. If reference equality is not sufficient, overload them, otherwise leave them as is. For primitive types they just work out of box.

它怎么可能是“好”或“坏”的东西?一种方法,另一种方法 - 操作者。如果引用相等是不够的,请将它们重载,否则保持原样。对于原始类型,它们只能在盒子外工作。

#2


33  

string x = "hello";
string y = String.Copy(x);
string z = "hello";

To test if x points to the same object as y:

要测试x是否指向与y相同的对象:

(object)x == (object)y  // false
x.ReferenceEquals(y)    // false
x.ReferenceEquals(z)    // true (because x and z are both constants they
                        //       will point to the same location in memory)

To test if x has the same string value as y:

要测试x是否与y具有相同的字符串值:

x == y        // true
x == z        // true
x.Equals(y)   // true
y == "hello"  // true

Note that this is different to Java. In Java the == operator is not overloaded so a common mistake in Java is:

请注意,这与Java不同。在Java中,==运算符没有重载,因此Java中常见的错误是:

y == "hello"  // false (y is not the same object as "hello")

For string comparison in Java you need to always use .equals()

对于Java中的字符串比较,您需要始终使用.equals()

y.equals("hello")  // true

#3


9  

Given Microsoft's current statement on equality operators == and !=, the conclusion is: == should just be syntactic sugar for Object.Equals():

鉴于微软目前关于等式运算符的陈述==和!=,结论是:==应该只是Object.Equals()的语法糖:

DO ensure that Object.Equals and the equality operators have exactly the same semantics

确保Object.Equals和相等运算符具有完全相同的语义

from http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx

来自http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx

That they are distinct, rather than just sugar, in hindsight, appears to be a mistake in their design.

事后看来,他们是独特的,而不仅仅是糖,在他们的设计中似乎是一个错误。

If you want to be certain you are getting IDENTITY comparison (when comparing references), then use ReferenceEquals instead.

如果您想确定您正在进行IDENTITY比较(比较参考时),请改用ReferenceEquals。

Unfortunately, the handling of == is so inconsistent, that I usually avoid it when manipulating someone else's custom classes, and just use the less readable Equals(a, b) or ReferenceEquals(a, b), depending on which meaning I want.

不幸的是,==的处理是如此不一致,我通常在操纵别人的自定义类时避免使用它,而只是使用不太可读的Equals(a,b)或ReferenceEquals(a,b),这取决于我想要的含义。

IMHO, it would be better for people to not implement == and != at all. Just let .Net default to Equals and ! Equals, and implement Equals as appropriate.

恕我直言,人们最好不要实现==和!=。只需将.Net默认为等于和!等于,并在适当时实施Equals。

If anyone has different reasoning, I'd like to hear it.

如果有人有不同的推理,我想听听。

(And yes, this is really confusing, given that Java existed first, and uses == to mean ReferenceEquals. But it is too late to alter .Net to behave that way. And we have Microsoft's own statement to that effect, in the link given above.)

(是的,这确实令人困惑,因为Java首先存在,并使用==来表示ReferenceEquals。但是改变.Net以这种方式行为为时已晚。而且我们有微软自己的声明,在链接中如上所述。)

#4


4  

I was going to post this as a comment on the accepted answer, but I think this deserves to be considered when determining which route to take.

我打算将此作为对已接受答案的评论发布,但我认为在确定采用哪条路线时应该考虑这一点。

dotnetfiddle: https://dotnetfiddle.net/gESLzO

dotnetfiddle:https://dotnetfiddle.net/gESLzO

Fiddle code:

小提琴代码:

    Object a = null;
    Object b = new Object();

    // Ex 1
    Console.WriteLine(a == b);
    // Ex 2
    Console.WriteLine(b == a);

    // Ex 3     
    Console.WriteLine(b.Equals(a));
    // Ex 4
    Console.WriteLine(a.Equals(b));

The first 3 WriteLine examples will work, but the fourth throws an exception. 1 and 2 use ==, which is a static method that does not require either object to be instantiated.

前3个WriteLine示例将起作用,但第四个抛出异常。 1和2使用==,这是一个静态方法,不需要实例化任何对象。

Example 3 works because b is instantiated.

示例3起作用,因为b被实例化。

Example 4 fails because a is null, and thus a method can not be called on a null object.

示例4失败,因为a为null,因此无法在null对象上调用方法。

Because I try to code as lazily as possible, I use ==, especially when working with scenarios where either object (or both) can be null. If I didn't, I'd have to do a null check, first, before being able to call .Equals().

因为我尝试尽可能懒惰地编码,所以我使用==,尤其是在使用其中任一对象(或两者)都可以为null的场景时。如果我没有,我必须首先进行空检查,然后才能调用.Equals()。

#5


1  

My understanding of the uses of both was this: use == for conceptual equality (in context, do these two arguments mean the same thing?), and .Equals for concrete equality (are these two arguments in actual fact the exact same object?).

我对两者用法的理解是这样的:使用==进行概念上的相等(在上下文中,这两个参数是否意味着相同的东西?),和.Equals用于具体的相等(实际上这两个参数是完全相同的对象吗? )。

Edit: Kevin Sheffield's linked article does a better job of explaining value vs. reference equality…

编辑:凯文谢菲尔德的链接文章在解释价值与参考平等方面做得更好......

#6


0  

You may want to use .Equals as someone may come along at a later time and overload them for you class.

你可能想要使用.Equals,因为有些人可能会在以后出现并为你上课超载。

#7


-1  

Two of the most often used types, String and Int32, implement both operator==() and Equals() as value equality (instead of reference equality). I think one can consider these two defining examples, so my conclusion is that both have identical meanings. If Microsoft states otherwise, I think they are intentionally causing confusion.

两种最常用的类型String和Int32将operator ==()和Equals()实现为值相等(而不是引用相等)。我认为可以考虑这两个定义的例子,所以我的结论是两者都有相同的含义。如果微软另有说明,我认为他们故意造成混淆。

#8


-1  

Operator == and Equals() both are same while we are comparing values instead of references. Output of both are same see below example.

当我们比较值而不是引用时,运算符==和等于()都是相同的。两者的输出相同,见下面的例子。

Example

    static void Main()
    {
        string x = " hello";
        string y = " hello";
        string z = string.Copy(x);
        if (x == y)
        {
            Console.WriteLine("== Operator");
        }
        if(x.Equals(y))
        {
            Console.WriteLine("Equals() Function Call");
        }
        if (x == z)
        {
            Console.WriteLine("== Operator while coping a string to another.");
        }
        if (x.Equals(y))
        {
            Console.WriteLine("Equals() Function Call while coping a string to another.");
        }
    }

Output:

输出:

  == Operator
  Equals() Function Call
  == Operator while coping a string to another.
  Equals() Function Call while coping a string to another.