3

这就是我所拥有的:

class A
{
  // The uniqueness of instance must be detected by this property
  public string Key { get; set; }

  // There are other properties
}

var set = HashSet<A>()

我的一般目的是:

  • 通过属性值提供set集合中实例的身份Key

  • 使此收集尽可能快地用于包含操作

回答以下问题可能有助于我实现这一目的:

  1. 什么用于运行方法,例如ContainsAdd必须确定实例的唯一性:GetHashCode() 还是 IEquatable?很可能 GetHashCode() as HashSet 声明搜索速度非常快。
  2. 默认String.GetHashCode()实现不保证 2 个不同字符串的哈希唯一性,那么如何在考虑性能的情况下提供唯一性?
  3. HashSet 是否完全使用了 IEquatable?

请注意,他的集合仅在运行时创建和销毁,不会保存到数据库中

4

1 回答 1

13

集合通常使用Object.GetHashCode()andObject.Equals()来获取哈希码并检查是否相等。除了最简单的对象外,没有办法Object.GetHashCode()为所有对象返回唯一的哈希码 - 哈希码只有 32 位宽,每个具有超过 32 位内部状态的对象都不能映射到唯一的哈希码。因此Object.Equals()用于在哈希码冲突的情况下检查是否完全相等。

因此,您必须使用合适的实现来覆盖这两种方法。

public override Int32 GetHashCode()
{
    // If this.Key may be null you have to handle this case.
    return this.Key.HashCode();
}

public override Boolean Equals(Object obj)
{
    var other = obj as A;

    return (other != null) && (this.Key == other.Key);
}

或者,您可以使用HashSet<T>构造函数接受IEqualityComparer<T>和外部化这两种方法,例如,如果您无法控制要添加到集合中的类型的源代码。只需使用合适的方法创建一个实现接口的类,并将该类的实例传递给HashSet<T>构造函数。

于 2013-01-17T19:22:05.827 回答