【问题标题】:Use "external" GetHashCode and Equals for Dictionary对字典使用“外部”GetHashCode 和 Equals
【发布时间】:2013-01-19 00:30:47
【问题描述】:

我想使用一个类作为字典中的键,它不会覆盖 Equals 或 GetHashCode。这是我不想修改的外部库中的一个类。

所以我想知道我是否可以只为一个字典使用自定义“GetHashCode”/“Equals”实现?我想知道是否可以使用 C++ std::maps 之类的东西

template < class Key,                      // map::key_type
           class T,                        // map::mapped_type
           class Compare = less<T>,        // map::key_compare
           class Alloc = allocator<T> >    // map::allocator_type
           > class map;

其中 Compare 可用于定义自定义比较。

我不想从类派生,因为对象是使用现有类在外部创建的。

我可以创建一个包含原始类的类,但这会改变对字典的访问。

感谢您的想法!

【问题讨论】:

  • 当您创建Dictionary 时,您可以为您的密钥传递IEqualityComparer&lt;&gt;msdn.microsoft.com/en-us/library/ms132072.aspx
  • 您可以为实现所需行为的键编写一个简单的包装类,然后将包装后的键传递给字典。
  • 为什么要做什么?任何类都适合作为键。
  • @MatthewWatson 不,它不会改变它,它只是告诉Dictionary 忽略实际对象的GetHashCode 实现并使用您在接口中提供的方法。跨度>
  • @MatthewWatson 没错,它不允许您修改 GetHashCode,但它允许您自定义比较两个键的方式,因此您可能根本不会使用 GetHashCode,但其他一些公共班级成员。

标签: c# dictionary


【解决方案1】:

当然 - 您可以实现 IEqualityComparer&lt;T&gt; 并将其传递给 the Dictionary&lt;,&gt; constructor。这正是构造函数的目的:)

例如:

public FooByNameEqualityComparer : IEqualityComparer<Foo>
{
    public int GetHashCode(Foo foo)
    {
        return foo.Name.GetHashCode();
    }

    public bool Equals(Foo x, Foo y)
    {
        return x.Name == y.Name;
    }
}

...

Dictionary<Foo, int> map = new Dictionary<Foo, int>(new FooByNameComparer());

【讨论】:

  • 这些年来我一直没有注意到 IEqualityComparer 中的 GetHashCode(object) 方法! (我一定以为这是普通的 Object.GetHashCode() 方法!)
【解决方案2】:

您可以将自定义IEqualityComparer&lt;TKey&gt; 传递给Dictionary&lt;TKey,TValue&gt; 的构造函数。相等比较器必须实现EqualGetHashCode

var dict = new Dictionary<MyKey,MyValue>(new MyKeyEqualityComparer());

【讨论】:

    【解决方案3】:

    你可以使用Dictionary Constructor (Int32, IEqualityComparer)

    public Dictionary(
        int capacity,
        IEqualityComparer<TKey> comparer
    )
    

    在哪里

    comparer 是:

    比较

    时使用的实现

    在实践中

    • 您定义了实现该接口的类型
    • 把它传递给这个ctor,所以那个类的方法用于字典键的相等识别。

    看起来是你想要的。

    【讨论】:

      猜你喜欢
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 2016-09-04
      • 2012-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多