对于值类型,引用类型和字符串,a.Equals(b)
和a == b
之间有什么区别?似乎a == b对于字符串来说效果很好,但我一直在尝试使用良好的编码实践。
答案 0 :(得分:36)
来自When should I use Equals and when should I use ==:
Equals方法只是一个虚拟方法 一个在System.Object中定义的,和 被任何一个班级选择覆盖 这样做。 ==运算符是一个 可以超载的运算符 课程,但通常有 身份行为。
对于==没有的参考类型 超载,它比较是否 两个参考文献指的是相同的 对象 - 这正是什么 Equals的实施确实在 System.Object的。
值类型不提供重载 对于==默认情况下。但是,大多数 由...提供的值类型 框架提供了自己的超载。 Equals的默认实现 对于值类型,由。提供 ValueType,并使用反射来制作 比较,这使得它 明显比a慢 通常类型特定的实现 将会。这个实现也 调用成对的引用等于 在被比较的两个值中。
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
答案 1 :(得分:12)
Here is a great blog post about WHY the implementations are different
本质上==将在编译时使用变量类型进行绑定,而.Equals将在运行时动态绑定。
答案 2 :(得分:10)
在最简写的答案中:
== opertator是检查身份。(即:a == b这两个是同一个对象吗?)
.Equals()是检查值。(即:a.Equals(b)都保持相同的值?)
有一个例外:
对于字符串和预定义值类型(例如 int , float 等),
运营商==将回答价值而不是身份。 (与使用.Equals())相同
答案 3 :(得分:8)
它们之间的一个显着区别是==
是一个静态二元运算符,它对一个类型的两个实例起作用,而Equals
是一个实例方法。重要的原因是你可以这样做:
Foo foo = new Foo()
Foo foo2 = null;
foo2 == foo;
但如果不抛出NullReferenceException
:
Foo foo = new Foo()
Foo foo2 = null;
foo2.Equals(foo);
答案 4 :(得分:7)
在简单的层面上,区别在于调用哪种方法。如果为相关类型定义,==方法将尝试绑定到operator ==。如果找不到值类型的==,它将进行值比较,对于引用类型,它将进行参考比较。 .Equals调用将对.Equals方法进行虚拟调度。
关于特定方法的作用,这些都在代码中。用户可以定义/覆盖这些方法并做任何他们喜欢的事情。理想情况下,这种方法应该是等效的(对双关语而言)并且具有相同的输出,但情况并非总是如此。
答案 5 :(得分:4)
帮助记住差异的一种简单方法是a.Equals(b)
更类似于
a == (object)b
。
.Equals()
方法不是通用的,并且接受“object”类型的参数,因此在与==运算符进行比较时,您必须考虑它,就好像右侧操作数首先被强制转换为对象一样
一个含义是,a.Equals(b)
几乎总是会为a
和b
返回一些值,无论其类型如何(正常的重载方法是返回false
b
是一种未知的类型)。如果没有可用于这些类型的比较,a == b
将抛出异常。
答案 6 :(得分:0)
“==
”是一个可以根据所比较的类型重载以执行不同操作的运算符。
“==
”执行的默认操作是a.Equals(b);
以下是如何为字符串类型重载此运算符:
public static bool operator == (string str1, string str2)
{
return (str1.Length == str2.Length;)
}
请注意,这与str1.Equals(str2);
派生类也可以覆盖和重新定义Equals()
。
就“最佳实践”而言,这取决于你的意图。
答案 7 :(得分:0)
对于字符串,您需要注意文化特定的比较。典型的例子是德国双S,看起来有点像b。这应该与“ss”匹配,但不是简单的==比较。
对于文化敏感的字符串比较使用:String.Compare(expected,value,StringComparison ....)== 0?您需要StringComparison重载。
答案 8 :(得分:0)
默认情况下,==
和.Equals()
除了在.Equals()
个实例上调用null
的可能性之外,都是等效的(这会给你NullReferenceException
)。但是,你可以独立地覆盖它们中的任何一个的功能(虽然我不确定这将是一个好主意,除非你试图解决另一个系统的缺点),这意味着你可以使它们不同
您会在过道的两侧找到关于使用者的人。我更喜欢操作员而不是功能。
如果您正在谈论字符串,那么使用string.Compare()
而不是其中任何一个选项可能更好。