C# 哈希集(.NET4)不是';t忽略c中的重复项#

C# 哈希集(.NET4)不是';t忽略c中的重复项#,c#,.net-4.0,duplicates,hashset,C#,.net 4.0,Duplicates,Hashset,我已经读到.net4中的HashSet将忽略所有重复项。所以我要做的是: HashSet<medbaseid> medbaseidlist = new HashSet<medbaseid>(); for (int i = 2; i <= rowCount; i++) { medbaseid medbaseid = new medbaseid() { mainClass = xlRange.C

我已经读到.net4中的HashSet将忽略所有重复项。所以我要做的是:

    HashSet<medbaseid> medbaseidlist = new HashSet<medbaseid>();

     for (int i = 2; i <= rowCount; i++)
     {
        medbaseid medbaseid = new medbaseid() { 
              mainClass = xlRange.Cells[i, 1].Value2.ToString(), 
              genName = xlRange.Cells[i, 2].Value2.ToString(),
              speciality = xlRange.Cells[i, 3].Value2.ToString(), 
              med_type_id = getId(xlRange.Cells[i, 4].Value2.ToString(),
              id = i-1
) 
        };

    medbaseidlist.Add(medbaseid);
 }

所以我现在的问题是:我做错了什么,或者这不是使用
哈希集的正确方法?提前感谢您的帮助。

这将取决于
medbaseid
类上的
GetHashCode()
Equals()
的实现

有关更多信息,请参阅


默认情况下,只有当对象实际上是同一个对象时,才会进行相等的比较。拥有相同的“内容”不足以使它们相等。如果希望具有相同“内容”的两个不同对象相等,则必须重写
Equals()
以实现该逻辑。每当重写
Equals()
时,还必须重写
GetHashCode()
,以使它们在哈希数据结构(如
HashSet
)中正常工作,
medbaseid
必须是一个
struct
,或者必须通过重写
Equals()
GetHashCode()
来定义基于类
medbaseid
的相等字段。或者,您也可以在启动时传入一个自定义的
IEqualityComparer

您是否覆盖了
GetHashCode
(和
等于
)?在标准实现中,不同的对象具有不同的hashcode,即使所有属性都相等。

听起来您需要实现
GetHashCode
和相等成员。埃里克·利珀特在这个问题上有自己的见解。

记住,平等在旁观者的眼里。具体地说,为了被认为是相等的,两个对象必须拥有与GetHashCode返回的哈希代码相同的哈希代码,并且必须为Equals返回true(在对象基类上找到两个虚拟/可重写的方法)

对于哈希集,还可以在构造函数中指定一个自定义相等比较器,用于执行相等比较和哈希代码生成

重点是,问题的可能原因是您的
medbaseID
…虽然其成员的值相等,但哈希代码和Equals实际上并不相等。Equals和hash代码的默认行为基于对象引用相等(实际上是对象的同一实例)


medbaseid
上覆盖Equals和GetHashCode。或者定义一个执行比较的
IEqualityComparer
,并在HashSet的构造函数中指定它。

同样值得一提的是,HashSet中的项应该是不可变的(或者至少考虑相等的字段应该是不可变的),否则,它们可能会在插入哈希集后被更改,从而哈希集将包含重复项。这样做没有帮助。我做错什么了吗?Equals方法和GetHashCode方法似乎考虑了不同的字段集。这将产生令人困惑的结果。您不需要为此添加ID。在最初的四个字段中,哪些值的组合为每个对象提供了唯一的值?即使只有这四个值的组合,您也需要在
Equals()
GetHashCode()
@Daniel Renshaw中使用相同的组合。GetHashCode返回一个int,所以我不能仅将我的4个值合并成一个唯一的id。可以吗?添加了Equals和GetHashCode,但我仍然有重复项,听起来你是说id值不同,对吗?如果是这样,您将得到不同的散列码,从而产生重复的条目…
returnsomecondition?true:false
可以减少为
returnsomecondition
   public override bool Equals(object obj)
    {
        medbaseid medb = (medbaseid)obj;
        return ((medb.id == this.id) && (medb.genName == this.genName) && (medb.mainClass == this.mainClass) && (medb.med_type_id == this.med_type_id) && (medb.speciality == this.speciality)) ? true : false;
    }

    public override int GetHashCode()
    {
        return id;
    }