首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用对象的字段作为通用字典键

使用对象的字段作为通用字典键
EN

Stack Overflow用户
提问于 2009-03-11 14:46:40
回答 5查看 101.8K关注 0票数 128

如果我想使用对象作为Dictionary的键,我需要重写哪些方法才能使它们以特定的方式进行比较?

假设我有一个a类,它有属性:

代码语言:javascript
复制
class Foo {
    public string Name { get; set; }
    public int FooID { get; set; }

    // elided
} 

我想创建一个:

代码语言:javascript
复制
Dictionary<Foo, List<Stuff>>

我希望具有相同FooIDFoo对象被视为同一组。我需要在Foo类中覆盖哪些方法?

总而言之:我想将Stuff对象分类到列表中,按Foo对象分组。Stuff对象将有一个FooID将它们链接到它们的类别。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-03-11 14:49:16

默认情况下,两个重要的方法是GetHashCode()Equals()。重要的是,如果两件事相等(Equals()返回true),它们具有相同的哈希码。例如,如果您希望将其作为匹配项,则可以“返回FooID;”作为GetHashCode()。您也可以实现IEquatable<Foo>,但这是可选的:

代码语言:javascript
复制
class Foo : IEquatable<Foo> {
    public string Name { get; set;}
    public int FooID {get; set;}

    public override int GetHashCode() {
        return FooID;
    }
    public override bool Equals(object obj) {
        return Equals(obj as Foo);
    }
    public bool Equals(Foo obj) {
        return obj != null && obj.FooID == this.FooID;
    }
}

最后,另一种选择是提供一个IEqualityComparer<T>来做同样的事情。

票数 162
EN

Stack Overflow用户

发布于 2009-03-11 15:27:33

因为您希望FooID作为组的标识符,所以应该使用它作为字典中的键,而不是Foo对象:

代码语言:javascript
复制
Dictionary<int, List<Stuff>>

如果要使用Foo对象作为键,则只需将GetHashCodeEquals方法实现为只考虑FooID属性。对于Dictionary而言,Name属性将是一个沉重的负担,因此您只需使用Foo作为int的包装器。

因此,最好直接使用FooID值,这样就不必实现任何东西,因为Dictionary已经支持使用int作为键。

编辑:

如果您无论如何都想使用Foo类作为键,那么IEqualityComparer<Foo>很容易实现:

代码语言:javascript
复制
public class FooEqualityComparer : IEqualityComparer<Foo> {
   public int GetHashCode(Foo foo) { return foo.FooID.GetHashCode(); }
   public bool Equals(Foo foo1, Foo foo2) { return foo1.FooID == foo2.FooID; }
}

用法:

代码语言:javascript
复制
Dictionary<Foo, List<Stuff>> dict = new Dictionary<Foo, List<Stuff>>(new FooEqualityComparer());
票数 33
EN

Stack Overflow用户

发布于 2009-03-11 14:48:58

对于Foo,您需要重写object.GetHashCode()和object.Equals()

字典将调用GetHashCode()来计算每个值的散列桶,并使用等于来比较两个Foo是否相同。

确保计算出良好的散列码(避免许多相等的Foo对象具有相同的散列码),但确保两个equals Foo具有相同的散列码。您可能希望从Equals-Method开始,然后(在GetHashCode()中) xor您在Equals中比较的每个成员的散列代码。

代码语言:javascript
复制
public class Foo { 
     public string A;
     public string B;

     override bool Equals(object other) {
          var otherFoo = other as Foo;
          if (otherFoo == null)
             return false;
          return A==otherFoo.A && B ==otherFoo.B;
     }

     override int GetHashCode() {
          return 17 * A.GetHashCode() + B.GetHashCode();
     }
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/634826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档