使用哈希码比较对象的属性

时间:2013-04-15 03:33:57

标签: c# hashcode gethashcode iequatable

我需要知道使用哈希码比较多个对象的方法。所以这是其中一个。

public class Test: IEquatable<Test>
{
    public Test()
    {
    }

    public string ID { get; set; }
    public string Name{ get; set; }

    public static int SafeGetHashCode<T>(this T value) where T : class
    {
        return value == null ? 0 : value.GetHashCode();
    }

    public override int GetHashCode()
    {
        int hash = 19;
        hash = hash * 31 + ID.SafeGetHashCode();
        hash = hash * 31 + Name.SafeGetHashCode();
        return hash;
    }

    public override bool isSame(object obj)
    {
         // compare objects here
    }
}

但是有2个错误。两者都是一样的。

'string'不包含'SafeGetHashCode'的定义,并且没有扩展方法'SafeGetHashCode'可以找到接受类型'string'的第一个参数(你是否缺少using指令或汇编引用?)

对于isSame(),我不知道如何编写代码。这个概念是比较所有对象,如果有2个相同的ID&amp;姓名,将他们组合在一起。

Item A = new Item();
Item B = new Item();
Item c = new Item();

A.ID = "Exam1";
A.Name = "Apple";

B.ID = "Exam1";
B.Name = "Orange";

C.ID = "Exam1";
C.Name = "Apple";

因此,项目A和C将组合在一起。

2 个答案:

答案 0 :(得分:2)

扩展方法必须是静态类的成员,它应该处理第一个错误。将SafeGetHashCode移出Test课程,以便将其用作String和其他参考类型的扩展程序:

public static class TestHashCodeExtension
{
    public static int SafeGetHashCode<T>(this T value) where T : class
    {
        return value == null ? 0 : value.GetHashCode();
    }
}

至于IEquatable<T>.Equals的实施(我假设您的isSame只是错误命名的方法,也奇怪地标有override - 任何.Net中都没有isSame类,尤其不在Object中):

  • 确保同时实施基础Equals IEquatable<T>.Equals
  • 请参阅IEquatable.Equals 中的示例,了解Equals次调用
  • 的实施情况

缩短样本:

public bool Equals(Test other) 
{
  return (other == null) ?
     false : (Id == other.Id) && (Name == other.Name);
}

public override bool Equals(Object obj)
{
  Test testObj = obj as Test;
  return testObj == null ? false : Equals(testObj);   
}

注意:通常Equals通常不需要先使用GetHashCodeDictionaryGetHashCode存在的主要原因)始终在调用Equals之前检查哈希码本身。在大多数情况下,GetHashCodeEquals都是按成员哈希/比较实现的。因此,除非您确定您的课程缓存GetHashCode的结果,否则没有实际的理由来检查Equals中的哈希码,因为您最终会触及每两次哈希码(并且Equals可以短路比较,如果第一个字段不相等,不像GetHashCode,需要使用所有/大多数字段来计算结果。)

答案 1 :(得分:2)

就我个人而言,我只是内联它 - 不需要额外的方法:

public override int GetHashCode()
{
    int hash = 19;
    hash = hash * 31 + (ID == null ? 0 : ID.GetHashCode());
    hash = hash * 31 + (Name == null ? 0 : Name.GetHashCode());
    return hash;
}

添加无约束的扩展方法会污染像intellisense这样的东西。