为什么 Rider 建议我使用解构?

问题描述

我正在编写这个类:

private class SameCellsComparer : EqualityComparer<Links> 
{
    public override bool Equals(Links t1,Links t2)
    {
        return t1 == null || t1.Equals(t2);
    }
    public override int GetHashCode(Links t)
    {
        // we suppose there will always be less than 100 000 000 items:
        return t.Item1.id + t.Item2.id * 100000000;
    }
}

但是 Rider 建议我在 GetHashCode(Links t) 上使用解构,如果我应用他的建议,我会得到这个:

private class SameCellsComparer : EqualityComparer<Links> 
{
    public override bool Equals(Links t1,Links t2)
    {
        return t1 == null || t1.Equals(t2);
    }
    public override int GetHashCode(Links t)
    {
        // we suppose there will always be less than 100 000 000 items:
        (Cell item1,Cell item2) = t;
        return item1.id + item2.id * 100000000;
    }
}

请不要谈论做坏的 GetHashCode() 原则,我只是要求转换为 (Cell item1,Cell item2) = t:它是否更安全、更快、更清洁?我不明白。

解决方法

那只是一个语法糖。 通过解构,您可以控制元组项的名称。

检查我创建的这个 gist

对于此 C# 代码:

using System;
public class C {
    public void M() {
        (string fff,String fff2) = C.Do();
        
        var l = C.Do();
    }
    
   public static (String a,String b) Do(){
       return ("aaa","bvvvv");
   }
}

编译器是这样看的:

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum,SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
public class C
{
    public void M()
    {
        ValueTuple<string,string> valueTuple = Do();
        string item = valueTuple.Item1;
        string item2 = valueTuple.Item2;
        ValueTuple<string,string> valueTuple2 = Do();
    }

    [return: TupleElementNames(new string[] {
        "a","b"
    })]
    public static ValueTuple<string,string> Do()
    {
        return new ValueTuple<string,string>("aaa","bvvvv");
    }
}

注意这一行:

  ValueTuple<string,string> valueTuple2 = Do();

代码大致相同。

screenshot of the gist