这是预期的C#4.0元组相等行为吗?

Mik*_*Two 15 tuples .net-4.0 c#-4.0

我在两个.NET 4.0的新Tuple <>实例之间使用.Equals和==之间看到了不同的行为.如果我在元组<>中的对象上重写了Equals并在元组上调用.Equals,则将调用Equals的覆盖.如果我在元组上使用==,则不会调用Equals的覆盖.这是设计,是否有意义?

编辑:从答案和评论,我可以告诉我,我不清楚.我知道Tuple <>是一个引用类型,对于引用类型==将检查标识(ReferenceEquals).但是,如果Tuple <>覆盖==来检查它包含的对象是否相等?为了保持一致,可能不是.

例如,如果我有一个简单的对象

public class NameAndNumber
{
    public int Number { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is NameAndNumber)
        {
            NameAndNumber other = (NameAndNumber)obj;
            return Number == other.Number && Name == other.Name;
        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我做这样的事情:

Tuple<NameAndNumber, NameAndNumber> left = new Tuple<NameAndNumber, NameAndNumber>(
      new NameAndNumber { Name = "one", Number = 1 }, 
      new NameAndNumber { Name = "two", Number = 2 });
Tuple<NameAndNumber, NameAndNumber> right = new Tuple<NameAndNumber, NameAndNumber>(
      new NameAndNumber { Name = "one", Number = 1 }, 
      new NameAndNumber { Name = "two", Number = 2 });
bool operatorResult = left == right;
bool equalsResult = left.Equals(right);
Console.Out.WriteLine("operatorResult = {0}  equalsResult = {1}", 
        operatorResult, equalsResult);
Run Code Online (Sandbox Code Playgroud)

我得到operatorResult = false equalsResult = true

我应该期待吗?

我知道NameAndNumber上Equals的实现并不"正确",它只是简化的示例代码.

我也尝试过实现IEquatable,==,!=和GetHashCode.结果相同.

Hen*_*man 14

您看到的结果来自设计妥协,现在Fuples和F#之间共享.重点是所有元组都确实被实现为引用类型,这不是那么明显.

Tuples是应该进行深度还是浅度相等检查的决定被转移到两个接口:IStructuralComparable,IStructuralEquatable.请注意,这些2现在也由Array类实现.


J.W*_*.W. 6

对于引用类型:==执行标识比较,即只有两个引用都指向同一个对象时才会返回true.虽然期望Equals()方法执行值比较,但如果引用指向等效的对象,它将返回true.

对于其中已经==引用类型NOT被重载,它比较两个引用是否指向同一个对象

  • 没有魔法 - 它只是重载了== /!=运算符; 你可以在反射器中看到这个作为op_Equality和op_Inequality(在System.String上).然而,**是**,例如`int` /`float`(在规范中定义)和`Nullable <T>`(使用"提升"运算符). (5认同)
  • 除了魔法的字符串.所以我想我正在寻找更多魔法.您是否期望值类型的元组进行值检查?它没有. (3认同)