令人惊讶的元组(内)相等性
直到今天,我对 .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 文档和各种博客给我留下了更多问题。根据我的收集,似乎 Tuple
这真的是元组应该有的行为吗?正如我到目前为止所解释的那样,结构兼容性实际上是对平等的附加约束,而不是放松吗?
如果是这样,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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
元组要求满足以下条件才能将对象视为“相等”:
因此,由于
Tuple
Tuples require the following to be true for the objects to be considered "equal":
So, because a
Tuple<object>
has a different generic parameter than aTuple<string>
, they are not equal even if the object is actually a reference to a string of the same value as the strongly-typedTuple<string>
.是的,我想说这就是元组应该有的行为方式。这里有两种不同的元组类型 -
Tuple
和Tuple
Tuple.Equals
的文档 指出其中两个条件是:如果您询问
Tuple
是否等于Tuple
一般来说,我认为将两种不同类型的实例视为彼此相等是一个非常糟糕的主意。它会引发各种各样的问题。
Yes, I'd say that's how tuples are supposed to behave. You've got two different tuple types here -
Tuple<string>
andTuple<object>
.The documentation for
Tuple<T1>.Equals
states that two of the conditions are:That's not true if you ask whether a
Tuple<string>
is equal to aTuple<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.
Tuple
实现IStructuralEquatable
- 按其名称,正是这样做的 - 检查结构和内容。您始终可以修改单元测试来检查元组的项目内容是否相等,而不是元组本身。
Tuple<T1>
implementsIStructuralEquatable
- 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.