Search code examples
c#rider

Why does Rider suggests me to use deconstruction?


I'm writing this class:

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;
    }
}

But Rider suggests me to use deconstruction on GetHashCode(Links t), and if I apply the suggestion, I get this:

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;
    }
}

Please don't talk about doing bad GetHashCode() principle, I'm only asking for the conversion to (Cell item1, Cell item2) = t: is it safer, faster, cleaner? I don't get it.


Solution

  • That is just a syntax sugar. With deconstruction you can control the name of the tuple items.

    Check this gist I created.

    For this C# code:

    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");
       }
    }
    

    Compiler see it like this:

    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");
        }
    }
    
    

    Notice that this lines:

      ValueTuple<string, string> valueTuple = Do();
            string item = valueTuple.Item1;
            string item2 = valueTuple.Item2;
            ValueTuple<string, string> valueTuple2 = Do();
    

    Are approximately the same code.

    screenshot of the gist