为HashSet实现自定义对象

时间:2015-06-22 04:43:42

标签: c# hash hashcode hashset

我为了算法目的而使用HashSet,但我在实现"自定义对象时遇到了问题"。做一些研究似乎应该:

  • 覆盖等于和GetHashCode(previous question here
  • 不应该生成带有可变对象的哈希码(here是它的Java,但我认为实现足够接近)

我的实施:

//Simplified version of actual class with key components
class customObject {
    public readonly uint column;
    public readonly char row;

    public customObject(uint column, char row) {
        this.column = column;
        this.row = row;
    }

    public override bool Equals(object obj) {
        return obj is customObj && !ReferenceEquals(this, obj);
    }

    /*where uint column and char row are readonly. HashSet add is not called
    until these variables are set with their lifetime value.*/
    public override int GetHashCode() {
        unchecked {
            var hashCode = row.GetHashCode();
            hashCode = (hashCode * 397) ^ column.GetHashCode();
            return hashCode;
        }
    }
}

//somwhere else
HashSet<customObject> s = new HashSet<customObject>();
for(int i = 0; i < 10; i++) {
    for(char c = 'A'; c < 'J'; c++) {
        s.add(new customObject((uint)i,c));
    }
 }

不幸的是,我无法将自定义对象添加到HashSet中。我可以确认在尝试添加对象后HashSet中的count个项为0。由于集合中没有项目,我怀疑我在实现中遗漏了一些内容,但是无法找到有关准备在HashSets中使用的自定义对象的完整答案/教程。

1 个答案:

答案 0 :(得分:1)

for(char c = 'A'; c < 'A'; c++)

调试器是你的朋友;检查你的循环情况。那个循环体永远不会运行。此外,在添加对象后,GetHashCode的实现永远不会导致Count == 0,而不会引发异常。最后,您对Equals的实施是错误的。

它确保相同的对象引用被认为是平等的,如果您要求参考相等,那么您不需要首先覆盖它。