从c#中的List或HashSet中删除重复项

时间:2013-04-16 17:25:20

标签: c# list hashset duplicate-removal

我有一个非常简单的测试方法,它返回一个具有大量重复项的List,但是当它没有时,我想我会尝试使用HashSet,因为它应该删除重复项,但看起来我需要覆盖Equals和GetHashCode但我真的很难理解我需要做什么。我希望得到一些指示。

HashSet<object> test = XmlManager.PeriodHashSet(Server.MapPath("../Xml/XmlFile.xml"));
foreach (Object period in test2)
{
    PeriodData pd = period as PeriodData;
    Response.Write(pd.PeriodName + "<br>");
}

我也尝试了以下

List<object> test = XmlManager.PeriodList(Server.MapPath("../Xml/XmlFile.xml"));
List<object> test2 = test.Distinct().ToList();
foreach (Object period in test2)
{
    PeriodData pd = period as PeriodData;
    Response.Write(pd.PeriodName + "<br>");
}

PeriodData对象是delcarewd,如下所示:

public class PeriodData
{
    private int m_StartYear = -9999999;
    private int m_EndYear = -9999999;
    private string m_PeriodName = String.Empty;

    public int StartYear
    {
        get { return m_StartYear; }
        set { m_StartYear = value; }
    }
    public int EndYear
    {
        get { return m_EndYear; }
        set { m_EndYear = value; }
    }
    public string PeriodName
    {
        get { return m_PeriodName; }
        set { m_PeriodName = value; }
    }
}

返回的PeriodName我想删除副本。

3 个答案:

答案 0 :(得分:4)

要使HashSet<T>生效,您至少需要覆盖Object.EqualsObject.GetHashCode。这使得散列算法能够通过值知道是什么使两个对象“不同”或相同。

在简化和改进代码方面,我建议做出两项重大改动:

首先,您应该使用HashSet<PeriodData>(或List<PeriodData>),而不是HashSet<object>

其次,您的PeriodData类应该实现IEquatable<PeriodData>,以便提供适当的哈希和相等。

答案 1 :(得分:1)

你必须决定两个时期相等的原因。如果两个句点的所有三个属性必须相同,那么您可以实现Equals:

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj.GetType() != this.GetType()) return false;
    PeriodData other = (PeriodData)obj;
    return m_StartYear == other.m_StartYear && m_EndYear == other.m_EndYear && string.Equals(m_PeriodName, other.m_PeriodName);
}

对于GetHashCode,您可以执行以下操作:

    public override int GetHashCode()
    {
        return (((m_StartYear * 397) ^ m_EndYear) * 397) ^ m_PeriodName.GetHashCode();
    }

(信用到期:这些是根据ReSharper代码生成工具生成的代码改编而来的。)

正如其他人所指出的那样,最好也实施IEquatable<T>

如果您无法修改该类,或者您不想修改它,则可以将相等比较逻辑放在另一个实现IEqualityComparer<PeriodData的类中,您可以将其传递给{{1}的相应构造函数。 }和HashSet<PeriodData>

答案 2 :(得分:0)

您必须实施IEquatable<T>才能使Distinct()正常工作。

框架如何知道怎么说&#34; 这两个对象是相同的&#34;如果你不这样做?您必须为框架提供一种比较对象的方法,这是IEquatable<T>实现的目的。