簡體   English   中英

C#與IEnumerable <T>的區別在於自定義IEqualityComparer

[英]C# Distinct on IEnumerable<T> with custom IEqualityComparer

這就是我想要做的。 我正在使用LINQ to XML查詢XML文件,它為我提供了一個IEnumerable <T >對象,其中T是我的“Village”類,填充了此查詢的結果。 有些結果是重復的,所以我想在IEnumerable對象上執行Distinct(),如下所示:

public IEnumerable<Village> GetAllAlliances()
{
    try
    {
        IEnumerable<Village> alliances =
             from alliance in xmlDoc.Elements("Village")
             where alliance.Element("AllianceName").Value != String.Empty
             orderby alliance.Element("AllianceName").Value
             select new Village
             {
                 AllianceName = alliance.Element("AllianceName").Value
             };

        // TODO: make it work...
        return alliances.Distinct(new AllianceComparer());
    }
    catch (Exception ex)
    {
        throw new Exception("GetAllAlliances", ex);
    }
}

由於默認的比較器不適用於Village對象,我實現了一個自定義的比較器,如AllianceComparer類中所示:

public class AllianceComparer : IEqualityComparer<Village>
{
    #region IEqualityComparer<Village> Members
    bool IEqualityComparer<Village>.Equals(Village x, Village y)
    {
        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) 
            return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return x.AllianceName == y.AllianceName;
    }

    int IEqualityComparer<Village>.GetHashCode(Village obj)
    {
        return obj.GetHashCode();
    }
    #endregion
}

Distinct()方法不起作用,因為無論是否有相同數量的結果。 另一件事,我不知道它是否通常可行,但我無法進入AllianceComparer.Equals()看看可能是什么問題。
我在互聯網上找到了這方面的例子,但我似乎無法讓我的實現工作。

希望有人在這里看到可能出錯的地方! 提前致謝!

問題出在你的GetHashCode 您應該更改它以返回AllianceName的哈希碼。

int IEqualityComparer<Village>.GetHashCode(Village obj)
{
    return obj.AllianceName.GetHashCode();
}

問題是,如果Equals返回true ,則對象應該具有相同的哈希碼,而對於具有相同AllianceName不同Village對象則不是這種情況。 由於Distinct通過在內部構建哈希表來工作,因此由於不同的哈希碼,您將最終得到完全不匹配的相等對象。

同樣,要比較兩個文件,如果兩個文件的散列不相同,則根本不需要檢查文件本身。 他們是不同的。 否則,您將繼續檢查它們是否真的相同。 這正是Distinct使用的哈希表的行為。

return alliances.Select(v => v.AllianceName).Distinct();

這將返回IEnumerable<string>而不是IEnumerable<Village>

或者換行

return alliances.Distinct(new AllianceComparer());

return alliances.Select(v => v.AllianceName).Distinct();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM