C# == 或 .Equals()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/144530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
== or .Equals()
提问by Dan
Why use one over the other?
为什么要使用一个?
采纳答案by John Millikin
== is the identity test. It will return true if the two objects being tested are in fact the same object. Equals()
performs an equality test, and will return true if the two objects consider themselves equal.
== 是身份测试。如果被测试的两个对象实际上是同一个对象,它将返回 true。Equals()
执行相等测试,如果两个对象认为自己相等,则返回 true。
Identity testing is faster, so you can use it when there's no need for more expensive equality tests. For example, comparing against null
or the empty string.
身份测试速度更快,因此您可以在不需要更昂贵的相等性测试时使用它。例如,比较null
或空字符串。
It's possible to overload either of these to provide different behavior -- like identity testing for Equals()
--, but for the sake of anybody reading your code, please don't.
可以重载其中任何一个以提供不同的行为——比如身份测试Equals()
——,但为了任何人阅读你的代码,请不要这样做。
Pointed out below: some types like String
or DateTime
provide overloads for the ==
operator that give it equality semantics. So the exact behavior will depend on the types of the objects you are comparing.
下面指出:某些类型喜欢String
或DateTime
为==
运算符提供重载,使其具有相等语义。因此,确切的行为将取决于您正在比较的对象的类型。
See also:
也可以看看:
回答by Jasper
use equals if you want to express the contents of the objects compared should be equal. use == for primitive values or if you want to check that the objects being compared is one and the same object. For objects == checks whether the address pointer of the objects is the same.
如果要表示比较对象的内容应该相等,则使用equals。将 == 用于原始值,或者如果您想检查被比较的对象是否是同一个对象。For objects == 检查对象的地址指针是否相同。
回答by Joshua DeWald
== is generally the "identity" equals meaning "object a is in fact the exact same object in memory as object b".
==通常是“身份”等于“对象a实际上与对象b在内存中完全相同的对象”。
equals() means that the objects logically equal (say, from a business point of view). So if you are comparing instances of a user-defined class, you would generally need to use and define equals() if you want things like a Hashtable to work properly.
equals() 表示对象在逻辑上相等(例如,从业务角度来看)。因此,如果您正在比较用户定义类的实例,并且您希望 Hashtable 之类的东西正常工作,则通常需要使用和定义 equals()。
If you had the proverbial Person class with properties "Name" and "Address" and you wanted to use this Person as a key into a Hashtable containing more information about them, you would need to implement equals() (and hash) so that you could create an instance of a Person and use it as a key into the Hashtable to get the information.
如果您有众所周知的 Person 类,它具有属性“Name”和“Address”,并且您想将此 Person 作为包含有关它们的更多信息的 Hashtable 的键,则需要实现 equals()(和 hash),以便您可以创建一个 Person 的实例并将其用作 Hashtable 中的键来获取信息。
Using == alone, your new instance would notbe the same.
单独使用 == ,您的新实例将不一样。
回答by Jason Olson
According to MSDN:
根据MSDN:
In C#, there are two different kinds of equality: reference equality (also known as identity) and value equality. Value equality is the generally understood meaning of equality: it means that two objects contain the same values. For example, two integers with the value of 2 have value equality. Reference equality means that there are not two objects to compare. Instead, there are two object references and both of them refer to the same object.
在 C# 中,有两种不同类型的相等:引用相等(也称为标识)和值相等。值相等是一般理解的相等的含义:它意味着两个对象包含相同的值。例如,两个值为 2 的整数值相等。引用相等意味着没有要比较的两个对象。相反,有两个对象引用并且它们都引用同一个对象。
...
...
By default, the operator == tests for reference equality by determining whether two references indicate the same object.
默认情况下,运算符 == 通过确定两个引用是否指示同一个对象来测试引用相等性。
回答by Peter K.
回答by Jason Baker
Another thing to take into consideration: the == operator may not be callable or may have different meaning if you access the object from another language. Usually, it's better to have an alternative that can be called by name.
要考虑的另一件事:如果您从另一种语言访问对象,== 运算符可能不可调用或可能具有不同的含义。通常,最好有一个可以通过名称调用的替代方法。
回答by John Rudy
Everyone else pretty much has you covered, but I have one more word of advice. Every now and again, you will get someone who swears on his life (and those of his loved ones) that .Equals
is more efficient/better/best-practice or some other dogmatic line. I can't speak to efficiency (well, OK, in certain circumstances I can), but I can speak to a big issue which will crop up: .Equals
requires an object to exist. (Sounds stupid, but it throws people off.)
其他人几乎都涵盖了你,但我还有一句忠告。时不时地,您会发现有人对他的生活(以及他所爱的人的生活)发誓.Equals
更有效/更好/最佳实践或其他一些教条路线。我不能谈效率(好吧,好吧,在某些情况下我可以),但我可以谈一个会突然出现的大问题:.Equals
需要一个对象存在。(听起来很愚蠢,但它让人们望而却步。)
You can't do the following:
您不能执行以下操作:
StringBuilder sb = null;
if (sb.Equals(null))
{
// whatever
}
It seems obvious to me, and perhaps most people, that you will get a NullReferenceException
. However, proponents of .Equals
forget about that little factoid. Some are even "thrown" off (sorry, couldn't resist) when they see the NullRefs start to pop up.
对我来说,也许对大多数人来说,很明显,你会得到一个NullReferenceException
. 然而,支持者.Equals
忘记了那个小事实。当他们看到 NullRefs 开始弹出时,有些人甚至被“抛弃”(抱歉,无法抗拒)。
(And years before the DailyWTFposting, I did actually work with someone who mandatedthat all equality checks be .Equals
instead of ==
. Even proving his inaccuracy didn't help. We just made damn sure to break all his other rules so that no reference returned from a method nor property was ever null, and it worked out in the end.)
(和前几年DailyWTF帖子,我居然做了与别人的工作谁规定的所有平等的检查是.Equals
不是的==
。即使证明他的不准确也没有帮助。我们只是做该死的肯定打破,这样从返回任何引用他的所有其他规则一个方法或属性从来没有为空,最后它解决了。)
回答by FlySwat
@John Millikin:
@约翰米利金:
Pointed out below: some value types like DateTime provide overloads for the == operator >that give it equality semantics. So the exact behavior will depend on the types of the >objects you are comparing.
下面指出:某些值类型(如 DateTime)为 == 运算符 > 提供了重载,从而赋予了它相等的语义。所以确切的行为将取决于您正在比较的 >objects 的类型。
To elaborate:
详细说明:
DateTime is implemented as a struct. All structs are children of System.ValueType.
DateTime 被实现为一个结构体。所有结构都是 System.ValueType 的子级。
Since System.ValueType's children live on the stack, there is no reference pointer to the heap, and thus no way to do a reference check, you must compare objects by value only.
由于 System.ValueType 的子级位于堆栈上,因此没有指向堆的引用指针,因此无法进行引用检查,您必须仅按值比较对象。
System.ValueType overrides .Equals() and == to use a reflection based equality check, it uses reflection to compare each fields value.
System.ValueType 覆盖 .Equals() 和 == 以使用基于反射的相等性检查,它使用反射来比较每个字段的值。
Because reflection is somewhat slow, if you implement your own struct, it is important to override .Equals() and add your own value checking code, as this will be much faster. Don't just call base.Equals();
因为反射有点慢,如果你实现自己的结构,重要的是覆盖 .Equals() 并添加你自己的值检查代码,因为这会快得多。不要只调用 base.Equals();
回答by GregUzelac
I have seen Object.ReferenceEquals() used in cases where one wants to know if two references refer to the same object
我已经看到 Object.ReferenceEquals() 用于想知道两个引用是否引用同一个对象的情况
回答by Guvante
Both Equals
and ==
can be overloaded, so the exact results of calling one or the other will vary. Note that ==
is determined at compile time, so while the actual implementation could change, which ==
is used is fixed at compile time, unlike Equals
which could use a different implementation based on the run time type of the left side.
二者Equals
并==
可以被重载,因此调用的一个或另一个会有所不同的精确结果。请注意,这==
是在编译时确定的,因此虽然实际实现可能会改变,但==
在编译时使用的是固定的,不像Equals
可以根据左侧的运行时类型使用不同的实现。
For instance string
performs an equality test for ==
.
例如,对string
执行相等测试==
。
Also note that the semantics of both can be complex.
另请注意,两者的语义可能很复杂。
Best practice is to implement equality like this example. Note that you can simplify or exclude all of this depending on how you plan on using you class, and that struct
s get most of this already.
最佳实践是像这个例子一样实现相等。请注意,您可以根据您计划如何使用您的课程来简化或排除所有这些struct
,这已经获得了大部分内容。
class ClassName
{
public bool Equals(ClassName other)
{
if (other == null)
{
return false;
}
else
{
//Do your equality test here.
}
}
public override bool Equals(object obj)
{
ClassName other = obj as null; //Null and non-ClassName objects will both become null
if (obj == null)
{
return false;
}
else
{
return Equals(other);
}
}
public bool operator ==(ClassName left, ClassName right)
{
if (left == null)
{
return right == null;
}
else
{
return left.Equals(right);
}
}
public bool operator !=(ClassName left, ClassName right)
{
if (left == null)
{
return right != null;
}
else
{
return !left.Equals(right);
}
}
public override int GetHashCode()
{
//Return something useful here, typically all members shifted or XORed together works
}
}