IComparable 是在字典中强制执行唯一键的最佳方法吗?

use*_*285 4 c# dictionary key icomparable primary-key

我有一个类 MyClass,我想将它作为字典的键,如下所示:

Dictionary<MyClass, string> dict = new Dictionary<MyClass, string>();
Run Code Online (Sandbox Code Playgroud)

我想确保 MyClass 是唯一的键,并且通过查看 来指定唯一性MyClass.UniqueProperty。我的第一个想法是重载该==运算符,但我发现 C# 不允许这样做。然后我找到了IComparable接口。这能起到作用吗?或者我应该重载 Object.Equals(obj) 吗?

Lua*_*aan 5

词典为定制平等规则做好了充分准备。这就是为什么它有一个采用IEqualityComparerhttps://msdn.microsoft.com/en-us/library/ms132072(v=vs.110).aspx)的构造函数。

由于您只关心字典上下文中的相等性,因此IEqualityComparer<MyClass>这是最直接的解决方案。

原始示例:

void Main()
{
  var dict = new Dictionary<MyClass, string>(new MyClassUniqueIdEqualityComparer());

  dict.Add(new UserQuery.MyClass { UniqueId = 1 }, "Hi!");

  dict.ContainsKey(new UserQuery.MyClass { UniqueId = 2 }).Dump(); // False
  dict.ContainsKey(new UserQuery.MyClass { UniqueId = 1 }).Dump(); // True
}

public class MyClass
{
  public int UniqueId { get; set; }
}

public class MyClassUniqueIdEqualityComparer : IEqualityComparer<MyClass>
{
  public bool Equals(MyClass a, MyClass b) 
  {
    return a.UniqueId == b.UniqueId;
  }

  public int GetHashCode(MyClass a)
  {
    return a.UniqueId.GetHashCode();
  }
}
Run Code Online (Sandbox Code Playgroud)

主要好处是相等规则仅按照相等比较器的定义应用。您不必确保派生类和基类之间的正确相等性 - 这一切都在字典和比较器的约定范围内。由于EqualsGetHashCode方法相对于字典来说不是虚拟的,因此即使在不同类型之间它们也允许相等,只要它们实现相同的接口 - 这是您确实不想用object.Equals,IEquatable<T>和 做的事情IComparable<T>