使用 C# 结构体作为字典键的最佳方法是什么?

问题描述 投票:0回答:2

我有一个 C# 结构,我将其用作标准 Dictionary 集合中的键。我已经为其 GetHashCode 和 Equals 编写了重写,但我有点不满意 Equals 被赋予了一个装箱对象而不是直接对我的结构类型的引用。

我可以做些什么来优化结构类型对字典的使用,以避免不必要的装箱操作?

(这不是过早的优化,而是完全适当的优化,非常感谢。)

c# .net optimization micro-optimization
2个回答
9
投票

您可以实现一个通用比较器:

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

然后将其用于字典构造函数

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

另一种方法是在IEquatable<MyStruct>

中实现
MyStruct
,例如:

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

    public MyStruct(int id)
    {
        Id = 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;
    }
}

然后可以使用默认构造函数初始化字典:

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

0
投票

您也可以尝试操作员超载。 检查下面的代码。

struct MyStruct
    {
        public int id;

        public static bool operator ==(MyStruct s1, MyStruct s2)
        {
            if (s1.id == s2.id)
                return true;
            return false;
        }

        public static bool operator !=(MyStruct s1, MyStruct s2)
        {
            if (s1.id == s2.id)
                return false;
            return true;
        }

        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;
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.