告诉HashSet使用IEquatable?

时间:2011-08-09 22:29:01

标签: c# .net

我在HashSet上读到的是它使用类的默认比较器。将第二个Spork添加到哈希集时,我期望下面的代码失败。我认为我对正在发生的事情的理解是不完整的。从HashSet构造函数的MSDN:

  

在比较集合中的值时使用的IEqualityComparer实现,或者为null使用集合类型的默认EqualityComparer实现。

那么什么是默认的比较器,我怎么能告诉.Net使用我自己的比较器呢?

public class Spork : IEquatable<Spork>
{
    public int Id { get; set; }


    public bool Equals(Spork other)
    {
        return other != null && other.Id == this.Id;
    }

    public override bool Equals(object obj)
    {
        var other = obj as Spork;
        return other != null && other.Id == this.Id;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

public class Bjork
{
    public static HashSet<Spork> Sporks { get; set; }
    public static void Main()
    {
        Sporks = new HashSet<Spork>();
        Sporks.Add(new Spork() { Id = 0 });
        Sporks.Add(new Spork() { Id = 0 });     // come on, please throw an exception
    }
}

2 个答案:

答案 0 :(得分:21)

使用您的相等方法 - 但是当您尝试添加相等的值时,HashSet<T>.Add不会抛出异常 - 它只返回false。

如果您更改最后两行以打印Add的返回值,您会看到它第一次返回True,然后False

答案 1 :(得分:1)

如果您的目标是像Dictionary一样工作并多次禁止相同的条目并抛出异常,则必须从HashSet和IEquatable继承:

class UniqueHashSet<T> : HashSet<T>, IEquatable<T>  

然后,当然,编写一个新的.Add()方法来隐藏基础添加。

但是,我确信有更好的方法。

或者,正如@Jon所说,它确实保留了一个独特的集合。