.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 (如intfloat等)
运算符==会回答价值而不是身份。 (与使用.Equals()相同)

一个简单的方法来帮助记住不同之处在于a.Equals(b)更类似于
a == (object)b

.Equals()方法不是generics的,接受一个types为“object”的参数,所以当与==运算符比较时,你必须考虑它,就好像右边的操作数先被转换为对象一样。

其中一个含义是a.Equals(b)几乎总是会为ab返回一些值,而不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()而不是其中的一个选项可能是一个好主意。