统一列表 (C#)

Uniquifying a list (C#)

我正在尝试使用自定义相等比较器从列表中删除重复项,但我似乎做错了。

简化示例:

class A
{
    public A(string Test) { this.Test = Test; }
    public string Test;
    public string ToString() { return Test; }
}

class AsComparer: EqualityComparer<A>
{
    public override bool Equals(A x, A y)
    {
        return (x.Test == y.Test);
    }

    public override int GetHashCode(A obj)
    {
        return obj.Test.GetHashCode();
    }
}

static private void Test()
{
    var As = new List<A> { new A("Test1"), new A("Test3"), new A("Test1"), new A("Test2") };
    As.Distinct(new AsComparer());
    As.Sort((e1, e2) => { return (e1.Test.CompareTo(e2.Test)); });
}

本returns合集"Test1"、"Test1"、"Test2"、"Test3"。我希望只有一个 "Test1",但似乎无法弄清楚如何正确地做到这一点。

有什么想法吗?

Distinct returns 和 IEnumerable<T>,它不对源列表本身进行操作。你必须做:

As = As.Distinct(new AsComparer()).ToList()

您也可以在此处包括您的排序:

As = As
    .Distinct(new AsComparer())
    .OrderBy(x => x.Test)
    .ToList()

Distinct() returns 一个全新的 IEnumerable, 所以:

var result = 
  As.
    Distinct(new AsComparer()).
    OrderBy(e => e.Test).
    ToList();

我认为在您的 class

上使用 IEquatable 会更好
class A : IEquatable<A>
{
    public A(string Test) { this.Test = Test; }
    public string Test;
    public bool Equals(A other)
    {
        return Equals(Test, other.Test);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != GetType()) return false;
        return Equals((A)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            unchecked
            {
                return Test.GetHashCode();
            }
        }
    }

    public string ToString() { return Test; }
}

那你就可以

var result = As.Distinct().OrderBy(x => x.Test).ToList();