重载等于()和操作符==的MSDN指南状态:
默认情况下,运算符==通过确定两个引用是否指示相同的对象来测试引用相等性,因此引用类型不需要实现运算符==才能获得此功能。当一个类型是不可变的,这意味着不能更改实例中包含的数据,重载操作符==来比较值相等而不是引用相等是有用的,因为作为不可变对象,只要它们具有相同的值,它们就可以被认为是相同的。不建议使用不可变类型的重写运算符==。。
有人能解释一下大胆背后的理由吗?
编辑--而且,这个准则是否只与==操作符相关,还是也适用于Equals方法?
发布于 2010-12-28 15:46:38
我的猜测是让事情像.NET中内置的类型那样运作,即==应该在可能的情况下像引用相等一样工作,而在可能的情况下,它应该像值相等一样工作。考虑一下==和Equals之间的实际差异
object myObj = new Integer(4);
object myObj2 = new Integer(4);
//Note that == is only called if the ref'd objects are cast as a type
//overloading it.
myObj == myObj2; //False (???)
myObj.Equals(myObj2); //True (This call is virtual)
//Set the references equal to each other -- note that the operator==
//comparison now works.
myObj2 = myObj;
myObj == myObj2; //True
myObj.Equals(myObj2); //True这种行为当然是不一致和令人困惑的,特别是对于新的程序员来说--但它表明了引用比较和值比较之间的区别。
如果您遵循此MSDN准则,您将遵循诸如string之类的重要类所采取的指导方针。基本上-如果使用==的比较成功,程序员就会知道,只要所涉及的引用没有分配给新的对象,这种比较总是会成功的。程序员不必担心对象的内容是不同的,因为它们永远不会不同:
//Mutable type
var mutable1 = new Mutable(1);
var mutable2 = mutable1;
mutable1 == mutable2; //true
mutable1.MutateToSomethingElse(56);
mutable1 == mutable2; //still true, even after modification
//This is consistent with the framework. (Because the references are the same,
//reference and value equality are the same.) Consider if == were overloaded,
//and there was a difference between reference and value equality:
var mutable1 = new Mutable(1);
var mutable2 = new Mutable(1);
mutable1 == mutable2; //true
mutable1.MutateToSomethingElse(56);
mutable1 == mutable2; //oops -- not true anymore
//This is inconsistent with, say, "string", because it cannot mutate.归根结底,这个指南没有真正的技术原因--它只是与框架中的其他类保持一致。
发布于 2010-12-28 14:31:13
假设您有一个可变类型A,并且创建一个或多个类型A的对象。如果集合中已经存在该对象,则向该集合添加一个对象应该会失败。
现在假设向集合中添加一个对象,然后更改其属性,使其与集合中的另一个对象相等。您已经创建了一个非法状态,其中集合中有两个相等的对象。
https://stackoverflow.com/questions/4546720
复制相似问题