元组==混乱

时间:2012-03-22 16:39:48

标签: c# .net tuples equality

假设我定义了两个元组:

Tuple<float, float, float, float> tuple1 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f);
Tuple<float, float, float, float> tuple2 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f);

如果我尝试比较元组,我会得到不同的结果

bool result1 = (tuple1 == tuple2);    // FALSE
bool result2 = tuple1.Equals(tuple2); // TRUE

我希望两个调用都返回true。 ==比较究竟是什么?

3 个答案:

答案 0 :(得分:32)

对于Tuple,==正在比较对象引用,因为它不会重载 ==运算符。由于对象是等效的,但不是相同的特定实例,Equals()返回true==返回false

许多类型不会重载==,有些人更喜欢区分Equals()等价和==参考相等。

此外,依靠==进行等效可能会导致一些奇怪之处:<​​/ p>

public bool AreSame<T>(T first, T second) where T : class
{
    return first == second;
}

上面的代码将始终检查引用相等性,因为在编译时将无约束泛型视为object,因此如果该方法不是虚拟的,您将获得对象的版本(即使类型,例如string重载==)。

这样使用上面的代码:

var x = "Hello";
var y = "H";

// doing concat to avoid string interring
AreSame(x, y+"ello");

是的,字符串是等价的,是Tstring,但是==绑定到对象的==,因为泛型是不受约束的,因此这将返回{ {1}}即使具有显式false参数的相同代码将返回string

答案 1 :(得分:10)

==正在比较对象引用。 Tuple类不会使==运算符超载,因此您需要使用.Equals

答案 2 :(得分:9)

元组的

==只能看到引用,因此你会看到它是假的。

PS:推荐的方法是做类似的事情:

var tuple1 = Tuple.Create(1.0f, 2.0f, 3.0f, 4.0f)