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方法
operator ==
可重载运算符
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方法
operator ==
可重载运算符
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.