惊人的元组(in)平等

直到今天,我对.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总是被认为是不相等的,无论两个实例都可以包装同一个对象(盒装或类型转换 – 它都是相同的)。

这真的是Tuples应该如何表现吗? 结构兼容性实际上是对平等的另一个限制,而不是放松,因为我一直在解释它吗?

如果是这样,BCL中还有什么可以用来满足上述unit testing的期望吗?

先感谢您!

对于要被视为“相等”的对象,元组需要满足以下条件:

  • 必须是具有与当前对象相同数量的通用参数的Tuple对象。
  • 每个通用参数必须与另一个相同。
  • 元组的每个成员必须具有与另一个成员相同的值。

因此,因为Tuple具有与Tuple不同的generics参数,所以即使该对象实际上是对与强类型的Tuple具有相同值的字符串的引用,它们也不相等。

是的,我会说这是元组应该如何表现的。 你在这里有两种不同的元组类型 – TupleTuple

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

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

如果您询问Tuple是否等于Tuple ,则不是这样,因此它返回false。

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

这真的是Tuples应该如何表现吗? 结构兼容性实际上是对平等的另一个限制,而不是放松,因为我一直在解释它吗?

Tuple实现了IStructuralEquatable – 它的名字就是这样 – 检查结构和内容。

您可以随时重新进行unit testing以检查元组的Item内容是否相等,而不是Tuple本身。