C#覆盖Dictionary ContainsKey

时间:2014-02-06 12:20:37

标签: c# dictionary override

我无法找到任何合适的代码来完成我需要的工作。

我正在使用Dict.ContainsKey但是由于我总是创建我需要查找的Key这一事实,我总是为ContainsKey弄错(因为hashKey是不同的,我创建的密钥我想一直检查)。

在这种情况下,有人可以建议如何覆盖包含密钥或如何处理密钥比较? 我的字典看起来像 Dictionary<someObj, int>

public class someObj
{
    public int someobjParam {get;set;}
    public int someobjParamTwo {get;set;}
}

2 个答案:

答案 0 :(得分:10)

您无需覆盖ContainsKey - 您需要 覆盖Equals中的GetHashCodesomeObj(应重命名)为了符合.NET命名约定,btw),您需要将IEqualityComparer<someObj>传递给Dictionary<,> constructor。无论哪种方式,该代码用于比较密钥(并从中获取哈希码)。

基本上,您需要使Equals确定相等,并使GetHashCode为相同的对象返回相同的代码,并为不同的对象返回理想的不同代码 - 有关详细信息,请参阅Eric Lippert's article on GetHashCode

此外,您应该考虑使someObj不可变:可变字典键通常是一个坏主意,就好像您在使用它作为字典中的键之后以哈希码敏感方式修改键时,您赢了'能够再次找到它。如果您的自定义类型的要点确实是一个键,那么只需将其设为不可变。

为简单起见,您还应考虑使someObj实现IEquatable<someObj>,并考虑是否适合成为结构而不是类。如果您实施IEquatable<someObj>,则以一致的方式覆盖object.Equals。通常,object.Equals实现只会调用强类型IEquatable<T>.Equals实现。

答案 1 :(得分:5)

您不需要覆盖ContainsKey,而是在考虑两个密钥相等时指示字典。

一种方法是在密钥类中实现IEquatable<someObj>。如果您的应用程序中的平等概念是全局性的,请执行此操作:

public class someObj : IEquatable<someObj>
{
    public int someobjParam {get;set;}
    public int someobjParamTwo {get;set;}

    // override GetHashCode() and Equals(); for an example
    // see http://msdn.microsoft.com/en-us/library/ms131190%28v=vs.110%29.aspx
}

另一个是通过实现IEqualityComparer<someObj>并将其传递给字典的构造函数。