.Equals和==之间的区别是什么?
对于值types,引用types和string, a.Equals(b)
和a == b
什么区别? 看起来好像一个== b工作正常的string,但我试图确保使用良好的编码做法。
从什么时候应该使用Equals,什么时候应该使用== :
Equals方法只是在System.Object中定义的一个虚拟方法,并被任何类select去覆盖。 ==运算符是一个可以被类重载的运算符,但它通常具有身份行为。
对于==没有被重载的引用types,它比较两个引用是否引用同一个对象 – 这正是Equals在System.Object中的实现。
默认情况下,值types不提供==的重载。 但是,框架提供的大多数值types都提供了自己的超载。 值types的Equals的默认实现由ValueType提供,并使用reflection进行比较,这使得它比通常的types特定的实现要慢得多。 这个实现还在被比较的两个值内调用Equals。
using System; public class Test { static void Main() { // Create two equal but distinct strings string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); Console.WriteLine (a==b); Console.WriteLine (a.Equals(b)); // Now let's see what happens with the same tests but // with variables of type object object c = a; object d = b; Console.WriteLine (c==d); Console.WriteLine (c.Equals(d)); } }
这个简短的示例程序的结果是
True True False True
这里有一篇关于为什么实现不同的好博客文章 。
本质上==将在编译时使用variablestypes进行绑定,并且.Equals将在运行时dynamic绑定。
在一个简单的层面上,区别在于哪个方法被调用。 如果为相关types定义,==方法将尝试绑定到运算符==。 如果没有find值types==它会做一个值比较和参考types,它会做参考比较。 .Equals调用将在.Equals方法上进行虚拟调度。
至于具体的方法是什么,这一切都在代码中。 用户可以定义/覆盖这些方法,并做任何他们想要的。 理想情况下,这种方法应该是等价的(抱歉双关语),并具有相同的输出,但事实并非总是如此。
它们之间的一个显着差异是==
是一个静态二元运算符, Equals
一个types的两个实例起作用,而Equals
是一个实例方法。 这个重要的原因是你可以这样做:
Foo foo = new Foo() Foo foo2 = null; foo2 == foo;
但是如果不抛出NullReferenceException
你不能这样做:
Foo foo = new Foo() Foo foo2 = null; foo2.Equals(foo);
在最简单的答案:
== opertator是检查身份。 (即:a == b这两个是同一个对象吗?)
.Equals()是检查值。 (即:a.Equals(b)都保持相同的值?)
有一个例外:
对于string和预定义的值types (如int , float等)
运算符==会回答价值而不是身份。 (与使用.Equals()相同)
一个简单的方法来帮助记住不同之处在于a.Equals(b)
更类似于
a == (object)b
。
.Equals()
方法不是generics的,接受一个types为“object”的参数,所以当与==运算符比较时,你必须考虑它,就好像右边的操作数先被转换为对象一样。
其中一个含义是a.Equals(b)
几乎总是会为a
和b
返回一些值,而不pipetypes如何(正常的重载方法是如果b
是未知types,则返回false
)。 如果没有这些types的可用比较, a == b
就会抛出一个exception。
“ ==
”是一个可以重载的运算符,根据被比较的types执行不同的事情。
( ==
执行的默认操作是a.Equals(b);
以下是如何为stringtypes重载此运算符:
public static bool operator == (string str1, string str2) { return (str1.Length == str2.Length;) }
请注意,这是不同于str1.Equals(str2);
派生类也可以覆盖和重新定义Equals()
。
就“最佳实践”而言,这取决于你的意图。
对于string,你要小心文化的具体比较。 典型的例子是德国的双S,看起来有点像b。 这应该与“ss”相匹配,但并不是简单的==比较。
对于文化敏感的string比较使用:String.Compare(expected,value,StringComparison ….)== 0? 与您需要的StringComparison超载。
默认情况下,除了在null
实例上调用.Equals()
(这会给你一个NullReferenceException
)之外, ==
和.Equals()
都是等价的。 但是,你可以独立地重写它们中的任何一个的function(虽然我不确定这是否是一个好主意,除非你试图解决另一个系统的缺点),这意味着你可以使它们不同。
你会在通道的两边find使用的人。 我更喜欢操作员而不是function。
如果你正在讨论string,那么使用string.Compare()
而不是其中的一个选项可能是一个好主意。