2012-11-11 3 views
11

Ich las ein Buch über Linq und sah, dass die Distinct-Methode eine Überladung hat, die einen Vergleich erfordert. Dies wäre eine gute Lösung für ein Problem, das ich habe, wo ich die verschiedenen Entitäten aus einer Auflistung abrufen möchte, aber den Vergleich in der Entitäts-ID haben soll, auch wenn die anderen Eigenschaften unterschiedlich sind.Wie verwende ich einen benutzerdefinierten Vergleich mit der Linq Distinct-Methode?

Nach dem Buch, wenn ich ein Gribulator Unternehmen habe, soll ich in der Lage sein, einen Vergleich wie diese erstellen ...

private class GribulatorComparer : IComparer<Gribulator> { 
    public int Compare(Gribulator g1, Gribulator g2) { 
    return g1.ID.CompareTo(g2.ID); 
    } 
} 

... und es dann wie folgt verwenden ...

List<Gribulator> distinctGribulators 
    = myGribulators.Distinct(new GribulatorComparer()).ToList(); 

jedoch ergibt dies folgende Compiler-Fehler ...

‚System.Collections.Generic.List‘ enthält keine Definition für ‚Distinct‘ und die beste Erweiterung -Methodenüberladung ‚System.Linq.Enumerable .Distinct (System.Collections.Generic.IEnumerable, System.Collections.Generic.IEqualityComparer) 'hat einige ungültige Argumente

Argument 2: kann aus nicht konvertieren 'LinqPlayground.Program.GribulatorComparer' auf' System.Collections.Generic.IEqualityComparer '

Ich habe ein wenig gesucht, und habe viele Beispiele gesehen, die Code wie diese verwenden, aber keine Beschwerden über Compilerfehler.

Was mache ich falsch? Ist dies der beste Weg, dies zu tun? Ich möchte hier eine einmalige Lösung, also nicht den Code für die Entität selbst ändern. Ich möchte, dass die Entity normal bleibt, aber nur an diesem einen Ort, vergleiche nur nach ID.

Danke für jede Hilfe.

+0

Vergessen zu fügen, ich benutze VS2012, und so .NET 4.0 in C# –

Antwort

13

Sie die Umsetzung Ihrer comparer als IComparer<T> erfordert die LINQ -Methodenüberladung eine Implementierung von IEqualityComparer:

private class GribulatorComparer : IEqualityComparer<Gribulator> { 
    public bool Equals(Gribulator g1, Gribulator g2) { 
    return g1.ID == g2.ID; 
    } 
} 

edit:

Zur Verdeutlichung der IComparer Schnittstelle kann für die Sortierung verwendet werden, wie das ist im Grunde, was die Compare() Methode tut.

So:

items.OrderBy(x => new ItemComparer()); 

private class ItemComparer : IComparer<Item> 
{ 
    public int Compare(Item x, Item y) 
    { 
     return x.Id.CompareTo(y.Id) 
    } 
} 

Welche Ihre Sammlung mit, dass comparer sortieren wird jedoch bietet LINQ eine Art und Weise, dass für einfache Felder zu tun (wie ein int Id).

items.OrderBy(x => x.Id); 
+0

Danke Peter, das erklärt es! Das Beispiel, das ich in dem Buch benutzte, war für OrderBy, aber er hatte sich darauf bezogen, von wo er Distinct diskutiert hatte, und ich hatte nicht die Tatsache aufgegriffen, dass ich eine andere Schnittstelle brauchte. War im Buch nicht wirklich klar :( –

+0

Übrigens, weißt du, ob es eine Möglichkeit gibt, das mit einer anonymen Funktion zu tun, anstatt eine eigene Klasse für den Vergleicher zu erstellen? Scheint wie Overkill –

+0

So weit Wie ich weiß, gibt es das nicht Ich habe sogar darüber nachgedacht, Linq-Operatoren mit solchen Dingen zu überlasten –

Verwandte Themen