Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most optimal way to use a C# struct as the key of a dictionary?

I have a C# struct which I use as the key in a standard Dictionary collection. I've written overrides for both its GetHashCode and Equals, but I'm a little unhappy that Equals is given a boxed object instead of a reference to my struct type directly.

Is there anything I can do to optimize my use of Dictionary with my struct type to avoid the unnecessary boxing operation?

(This isn't premature optimization but entirely appropriate optimization, thank you very much.)

like image 201
billpg Avatar asked Aug 24 '17 08:08

billpg


Video Answer


1 Answers

You could implement a generic comparer:

public class MyStructComparer : IEqualityComparer<MyStruct>
{
    public bool Equals(MyStruct x, MyStruct y)
    {
        // ...
    }
    public int GetHashCode(MyStruct obj)
    {
        // ...
    }
}

Then use that for the dictionary constructor:

var myStructDict = new Dictionary<MyStruct, string>(new MyStructComparer());

Another way is to implement IEquatable<MyStruct> in MyStruct, for example:

public struct MyStruct: IEquatable<MyStruct>
{
    public int Id;

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        return obj is MyStruct && Equals((MyStruct)obj);
    }

    public bool Equals(MyStruct other)
    {
        return this.Id == other.Id;
    }

    public override int GetHashCode()
    {
        return this.Id;
    }
}

Then the dictionary can be initialized with the default constructor:

var myStructDict = new Dictionary<MyStruct, string>();
like image 141
Tim Schmelter Avatar answered Sep 30 '22 06:09

Tim Schmelter