Frage

Hier ist, was ich versuche zu tun. Ich Abfrage eine XML-Datei in XML mithilfe von LINQ, die mir ein IEnumerable<T> Objekt gibt, wo T meine „Village“ Klasse ist, mit den Ergebnissen dieser Abfrage gefüllt. Einige Ergebnisse werden dupliziert, so dass ich einen Distinct () auf dem IEnumerable-Objekt durchführen mag, etwa so:

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);
    }
}

Wie der Standardvergleich nicht für das Dorf Objekt funktionieren würde, implementiert ich einen benutzerdefinierten ein, wie hier in der Klasse AllianceComparer gesehen:

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
}

Die Distinct () Methode nicht funktioniert, wie ich genau die gleiche Anzahl von Ergebnissen mit oder ohne sie. Eine andere Sache, und ich weiß nicht, ob es in der Regel möglich ist, aber ich kann nicht Schritt in AllianceComparer.Equals (), um zu sehen, was das Problem sein könnte.
Ich habe Beispiele dafür im Internet zu finden, aber ich kann nicht scheinen, um meine Implementierung Arbeit zu machen.

Ich hoffe, jemand hier vielleicht sehen, was hier falsch sein könnte! Vielen Dank im Voraus!

War es hilfreich?

Lösung

Das Problem ist, mit Ihrem GetHashCode. Sie sollten es ändern, anstatt den Hash-Code von AllianceName zurückzukehren.

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

Die Sache ist, wenn Equals kehrt true, sollten die Objekte haben den gleichen Hash-Code, der nicht der Fall für verschiedene Village Objekte mit gleichen AllianceName ist. Da Distinct intern durch den Bau einer Hash-Tabelle funktioniert, werden Sie sich mit gleichen Objekten beenden, die überhaupt auf verschiedene Hash-Codes aufgrund wird nicht abgestimmt.

In ähnlicher Weise zwei Dateien zu vergleichen, wenn der Hash aus zwei Dateien sind nicht die gleichen, Sie brauchen nicht die Dateien zu überprüfen gar selbst. Sie unterschiedlich sein. Andernfalls werden Sie auch weiterhin überprüfen, um zu sehen, ob sie wirklich gleich sind oder nicht. Das ist genau das, was die Hash-Tabelle, die verhält sie Distinct verwendet.

Andere Tipps

  

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

Das wäre eine IEnumerable<string> statt IEnumerable<Village> zurück.

oder ändern Sie die Zeile

return alliances.Distinct(new AllianceComparer());

return alliances.Select(v => v.AllianceName).Distinct();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top