2010-12-30 4 views
2

Ich habe mehrere Klassen in meiner Anwendung, die alle eine Name Eigenschaft haben, die ich als meine Basis für den Vergleich verwenden möchte (Distinct(), etc.). Da ich immer auf Name vergleichen werde, entschied ich mich, eine Schnittstelle zu extrahieren, ISomeComparedStuff, die einfach eine Name Property hat, die alle meine anderen Klassen implementieren. Ich habe eine Vergleichsklasse als solche nach oben:Linq Distinct mit einer einzigen Vergleichsklasse (und Schnittstelle)

public class MyComparer : IEqualityComparer<ISomeComparedStuff> 
{ 
    public bool Equals(ISomeComparedStuff x, ISomeComparedStuff y) 
    { 
      return x.Name == y.Name; 
    } 

    public int GetHashCode(ISomeComparedStuff obj) 
    { 
      return obj.Name.GetHashCode(); 
    } 
} 

Das einzige Problem ist, wenn ich versuche, dagegen zu kodieren:

public class SomeStuff : ISomeComparedStuff 
{ 
    ... 
} 

public class SomeMoreStuff : ISomeComparedStuff 
{ 
    ... 
} 

var someStuff = GetSomeStuff().Distinct(new MyComparer); 
var someMoreStuff = GetSomeMoreStuff().Distinct(new MyComparer); 

Ich bin ein Gussfehler bekommen (SomeStuff-ISomeComparedStuff). Gibt es eine Möglichkeit, dies zu tun, so brauche ich nur eine Vergleichsklasse, sonst müsste ich für jeden meiner Klassen eine erstellen (obwohl ich immer auf Name vergleichen werde)?

Hinweis: Ich verstehe diese Frage "Titel" braucht Hilfe. Irgendwelche Vorschläge wären großartig.

Antwort

2

Nicht sicher, ob dies eine gute Lösung ist oder nicht, aber wie wäre es damit, MyComparer zu einer generischen Klasse zu machen?

public class MyComparer<T> : IEqualityComparer<T> 
    where T: ISomeComparedStuff 
{ 
    public bool Equals(T x, T y) 
    { 
     return x.Name == y.Name; 
    } 

    public int GetHashCode(T obj) 
    { 
     return obj.Name.GetHashCode(); 
    } 
} 

Nachteil ist, Sie zu neuen haben eine entsprechende Version auf:

public static IEnumerable<T> DistinctByName<T>(this IEnumerable<T> values) 
    where T: ISomeComparedStuff 
{ 
    return values.Distinct(new MyComparer<T>()); 
} 
0

Vielleicht so etwas wie:

var someStuff = GetSomeStuff().Cast<ISomeComparedStuff>().Distinct(new MyComparer); 

oder die nicht-generic IEqualityComparer verwenden.

+0

ich diesen Ansatz mag:

var someStuff = GetSomeStuff().Distinct(new MyComparer<SomeStuff>()); var someMoreStuff = GetSomeMoreStuff().Distinct(new MyComparer<SomeMoreStuff>()); 

ein wenig erweitern, können Sie auch eine neue Erweiterung Methode wie diese machen könnte (vor allem, wenn es in einer anderen Erweiterungsmethode gekapselt wäre, zB DistinctByName()), aber Sie müssten die Elemente wieder in den ursprünglichen Typ umwandeln, sonst ist das resultierende 'IEnumerable ' wahrscheinlich ziemlich nutzlos. –

+0

Ja. Ich wäre besorgt, dass ich nach der Besetzung alle Daten verlieren würde. –

+0

Sie verlieren keine Daten. Übertragungen an eine Schnittstelle sind nicht verlustreich. –

Verwandte Themen