元组==混乱

lum*_*ck4 17 .net c# 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);
Run Code Online (Sandbox Code Playgroud)

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

bool result1 = (tuple1 == tuple2);    // FALSE
bool result2 = tuple1.Equals(tuple2); // TRUE
Run Code Online (Sandbox Code Playgroud)

我希望两个调用都能返回true.到底是什么==比较?

Jam*_*are 32

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

许多类型不会过载==,有些人更喜欢区分Equals()等价和==引用相等.

另外,依赖于==等价可能会导致一些奇怪:

public bool AreSame<T>(T first, T second) where T : class
{
    return first == second;
}
Run Code Online (Sandbox Code Playgroud)

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

因此以上代码的这种用法:

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

// doing concat to avoid string interring
AreSame(x, y+"ello");
Run Code Online (Sandbox Code Playgroud)

是的,字符串是等价的,是Tstring,但是由于泛型是不受约束的,所以它==被绑定到对象==,因此false即使具有显式string参数的相同代码将返回,这将返回true.


Kir*_*oll 10

==正在比较对象引用.本Tuple类不超载的==运营商,所以你需要使用.Equals.


man*_*lds 9

== 对于元组只会看到引用,因此你会看到它是错误的.

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

var tuple1 = Tuple.Create(1.0f, 2.0f, 3.0f, 4.0f)
Run Code Online (Sandbox Code Playgroud)

  • 一旦添加f,就可以删除`.0`,即`1f`,`2f`等. (2认同)