重写非不可变类型中的 == 运算符

发布于 2024-10-09 14:33:35 字数 542 浏览 8 评论 0原文

MSDN 重载 Equals() 和运算符的指南 ==< /a> 状态:

默认情况下,运算符 == 测试 通过确定 if 来引用相等性 两个参考文献表示相同 对象,因此引用类型不需要 实现运算符 == 以便 获得此功能。当一个类型 是不可变的,这意味着数据 实例中不能包含 更改为,重载运算符 == 为 比较值相等而不是 引用相等很有用 因为,作为不可变的对象,它们 可以认为是相同的,只要 它们具有相同的值。 压倒一切 非不可变类型中的运算符 == 是 不推荐。

谁能解释一下粗体背后的原因吗?

编辑 - 另外,该指南仅与 == 运算符相关,还是也适用于 Equals 方法?

The MSDN Guidelines for Overloading Equals() and Operator == state:

By default, the operator == tests for
reference equality by determining if
two references indicate the same
object, so reference types do not need
to implement operator == in order to
gain this functionality. When a type
is immutable, meaning the data
contained in the instance cannot be
changed, overloading operator == to
compare value equality instead of
reference equality can be useful
because, as immutable objects, they
can be considered the same as long as
they have the same value. Overriding
operator == in non-immutable types is
not recommended.

Can anyone explain the reasoning behind the bold?

EDIT - Also, is this guideline relevant to the == operator only, or is it meant for the Equals method as well ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

彩扇题诗 2024-10-16 14:33:35

我有根据的猜测是让事情像 .NET 中的内置类型一样运行,即 == 应该尽可能像引用相等一样工作,而 Equals 应该尽可能像值相等一样工作。考虑一下 ==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.

归根结底,该指南没有真正的技术原因——只是为了与框架中的其余类保持一致。

My educated guess would be to make things operate like the built in types in .NET do, namely that == should work like reference equality where possible, and that Equals should work like value equality where possible. Consider the actual difference between == and 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

This behavior is of course inconsistent and confusing, particularly to new programmers -- but it demonstrates the difference between reference comparisons and value comparisons.

If you follow this MSDN guideline, you are following the guideline taken by important classes such as string. Basically -- if a comparison using == succeeds, the programmer knows that that comparison will always succeed, so long as the references involved don't get assigned to new objects. The programmer need never worry about the contents of the objects being different, because they never will be different:

//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.

It boils down to that there's no real technical reason for the guideline -- it's just to remain consistent with the rest of the classes in the framework.

阪姬 2024-10-16 14:33:35

假设您有一个可变类型 A 并且创建了一个或多个类型 A 的对象。如果该对象已存在于集合中,则将对象添加到集合中应该会失败。

现在,假设您将一个对象添加到集合中,然后更改其属性,使其与集合中的另一个对象相等。您创建了一个非法状态,其中集合中存在两个相等的对象。

Assume you have a mutable type A and you create a set or objects of type A. Adding an object to the set should fail if this object already exists in the set.

Now let's say you add an object to the set, and then you change its properties so that it becomes equal to another object in the set. You've created an illegal state, where there are two objects in the set which are equal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文