2

我有一个非常简单的测试方法,它返回一个包含许多重复项的列表,但是当它没有时我想我会尝试 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 。

4

3 回答 3

4

为了使HashSet<T>工作,您至少需要覆盖Object.EqualsObject.GetHashCode。这就是允许散列算法通过值知道是什么使两个对象“不同”或相同的原因。

在简化和改进代码方面,我建议进行两项主要更改以使其工作:

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

其次,你的PeriodData类应该实现IEquatable<PeriodData>以提供正确的散列和相等性。

于 2013-04-16T17:30:59.633 回答
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,你可以将它传递给适当的构造函数HashSet<PeriodData>Enumerable.Distinct()

于 2013-04-16T17:49:49.963 回答
0

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

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

于 2013-04-16T17:30:55.773 回答