所以,当我现在是新手的比较新手时,我曾经认为这两件事是彼此的语法糖,即使用一个而不是另一个只是个人偏好.随着时间的推移,我发现即使在默认实现中,这两者也不是一回事(参见本章和本章).为了进一步混淆这个问题,每个都可以单独覆盖/重载,以具有完全不同的含义.
这是一件好事,有什么区别,什么时候/为什么要使用一个而不是另一个?
string x = "hello"; string y = String.Copy(x); string z = "hello";
要测试是否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)
要测试if是否x
具有相同的字符串值y
:
x == y // true x == z // true x.Equals(y) // true y == "hello" // true
请注意,这与Java不同.在Java中,==
运算符不会过载,因此Java中常见的错误是:
y == "hello" // false (y is not the same object as "hello")
对于Java中的字符串比较,您需要始终使用 .equals()
y.equals("hello") // true
MSDN对这两件事都有清晰而可靠的描述.
object.Equals方法
operator ==
可重载运算符
覆盖等于()和运算符的指南==
这是一件好事,有什么区别,什么时候/为什么要使用一个而不是另一个?
它怎么可能是"好"或"坏"的东西?一种方法,另一种方法 - 操作者.如果引用相等是不够的,请将它们重载,否则保持原样.对于原始类型,它们只能在盒子外工作.
微软表示,类实现者应该==
尽可能地表现出类似行为Equals
:
确保Object.Equals和相等运算符具有完全相同的语义
来自http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx
如果您想确定您正在进行IDENTITY比较(比较参考时),请ReferenceEquals
改用.
如果类实现者没有覆盖==
,那么在编译时,在基类中查找静态方法.如果此搜索到达Object
,则Object.==
使用.对于课程,这与ReferenceEquals
.
如果类文档不确定给定的类(来自微软以外的供应商)是否实现==
为Equals
或ReferenceEquals
(或理论上它们可能与这两者不同),
我有时会避免==
.相反,我使用的可读性较低,Equals(a, b)
或者ReferenceEquals(a, b)
取决于我想要的含义.
OTOH,ps2goat提出了一个很好的观点,即==
如果第一个操作数为null ,则使用avoidids exception(因为它==
是一个静态操作符).这是支持使用的论据==
.
删除了有争议的评论 ==
更新最新的Microsoft doc引用,来自2019年2月检索到的.Net 4.7.2,表明他们仍然打算两者表现相似:
Object.Equals方法
某些语言(如C#和Visual Basic)支持运算符重载.当类型重载相等运算符时,它还必须重写Equals(Object)方法以提供相同的功能.这通常通过根据重载的相等运算符编写Equals(Object)方法来实现,如下例所示.
注意:请参阅其他答案,了解==
静态方法与Equals
实例方法的结果.我并不是说行为是一样的; 我观察微软建议尽可能使两者相似.
我打算将此作为对已接受答案的评论发布,但我认为在确定采用哪条路线时应该考虑这一点.
dotnetfiddle:https://dotnetfiddle.net/gESLzO
小提琴代码:
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));
前3个WriteLine示例将起作用,但第四个抛出异常.1和2使用==
,这是一个静态方法,不需要实例化任何对象.
示例3起作用,因为b
实例化.
示例4因为a
is null
而失败,因此无法在null对象上调用方法.
因为我尝试尽可能懒惰地进行编码,所以我会使用==
,尤其是在处理任何一个对象(或两者)都可以为null的场景时.如果我没有,我必须先进行空检查,然后才能打电话.Equals()
.