令人惊讶的元组(内)相等性

发布于 2024-10-18 10:51:35 字数 628 浏览 2 评论 0原文

直到今天,我对 .NET Tuple 类的理解是它们将 Equals() 的实现委托给它们的内容,允许我“按值”对它们进行等同和比较。

然后这个测试出现了,让我出乎意料:

[TestMethod]
public void EquateTwoTuplesWithSameContent()
{
    var t1 = Tuple.Create("S");
    var t2 = Tuple.Create((object)t1.Item1);
    Assert.IsTrue(t1.Equals(t2)); // Boom!
}

阅读 MSDN 文档和各种博客给我留下了更多问题。根据我的收集,似乎 TupleTuple 总是被认为不相等,无论两个实例可能包装同一个对象(盒装或打字 - 都是一样的)。

这真的是元组应该有的行为吗?正如我到目前为止所解释的那样,结构兼容性实际上是对平等的附加约束,而不是放松吗?

如果是这样,BCL 中是否还有其他内容可以用来满足上述单元测试的期望?

先感谢您!

Until today, my understanding of .NET Tuple classes had been that they delegate their implementation of Equals() to their contents, allowing me to equate and compare them "by value".

Then this test came along and made a fool out of me:

[TestMethod]
public void EquateTwoTuplesWithSameContent()
{
    var t1 = Tuple.Create("S");
    var t2 = Tuple.Create((object)t1.Item1);
    Assert.IsTrue(t1.Equals(t2)); // Boom!
}

Reading through MSDN documentation and various blogs has left me with more questions. From what I gather, it would seem that Tuple<object> and Tuple<TWhatever> are always considered not equal, regardless of the fact that both instances may wrap the same object (boxed or typecast - it's all the same).

Is this really how Tuples are supposed to behave? Is structural compatibility actually an additional constraint on equality as opposed to a relaxation, as I've been interpreting it until now?

If so, is there anything else in the BCL that I can use to meet the expectations of the above unit test?

Thank you in advance!

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

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

发布评论

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

评论(3

唐婉 2024-10-25 10:51:35

元组要求满足以下条件才能将对象视为“相等”:

  • 必须是具有与当前对象相同数量的泛型参数的元组对象。
  • 这些通用参数中的每一个都必须具有相同的类型。
  • 元组的每个成员必须与另一个成员的相应成员具有相同的值。

因此,由于 TupleTuple 具有不同的泛型参数,因此即使对象实际上是对字符串的引用,它们也不相等。与强类型 Tuple 相同的值。

Tuples require the following to be true for the objects to be considered "equal":

  • Must be a Tuple object with the same number of generic parameter(s) as the current object.
  • Each of those generic parameters must be of the same type as the other.
  • Each member of the tuple must have the same value as the corresponding member of the other.

So, because a Tuple<object> has a different generic parameter than a Tuple<string>, they are not equal even if the object is actually a reference to a string of the same value as the strongly-typed Tuple<string>.

我一向站在原地 2024-10-25 10:51:35

是的,我想说这就是元组应该有的行为方式。这里有两种不同的元组类型 - TupleTuple

Tuple.Equals 的文档 指出其中两个条件是:

  • 它是一个 Tuple 对象。
  • 其单个组件与当前实例的类型相同。

如果您询问 Tuple 是否等于 Tuple,则事实并非如此,因此它会返回 false。

一般来说,我认为将两种不同类型的实例视为彼此相等是一个非常糟糕的主意。它会引发各种各样的问题。

Yes, I'd say that's how tuples are supposed to behave. You've got two different tuple types here - Tuple<string> and Tuple<object>.

The documentation for Tuple<T1>.Equals states that two of the conditions are:

  • It is a Tuple<T1> object.
  • Its single component is of the same type as the current instance.

That's not true if you ask whether a Tuple<string> is equal to a Tuple<object>, so it returns false.

In general I think it's a very bad idea for instances of two different types to be deemed equal to each other. It invites all kinds of issues.

葬花如无物 2024-10-25 10:51:35

这真的是元组应该有的行为方式吗?结构兼容性实际上是对平等的附加约束,而不是放松,正如我到目前为止一直在解释的那样?

Tuple实现 IStructuralEquatable - 按其名称,正是这样做的 - 检查结构和内容。

您始终可以修改单元测试来检查元组的项目内容是否相等,而不是元组本身。

Is this really how Tuples are supposed to behave? Is structural compatibility actually an additional constraint on equality as opposed to a relaxation, as I've been interpreting it until now?

Tuple<T1> implements IStructuralEquatable - which, by its name, does exactly that - checks the structure as well as the contents.

You could always rework your Unit test to check the Item contents of the tuple for equality, instead of the Tuple itself.

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