2010-12-20 8 views
0

Ich arbeite mit einer Bibliothek (TreeView in Gtk um genau zu sein), die Sie sortieren können, indem Sie eine Funktion übergeben, die zwei Zeilen vergleicht. Eine vereinfachte Version der Funktion Signatur könnte wie folgt aussehen:Wie kann ich diese generische Methode flexibler machen?

int SomeSortFunc (Foo foo1, Foo foo2) 
{ 
    // Return -1 if foo1 < foo2, 0 if foo1 == foo2, 1 if foo1 > foo2 
} 

Ich kann einfach nicht Foo.CompareTo (Foo) implementieren, weil ich irgendwie anders je nach dem Zusammenhang mag. Es gibt mehrere Felder in Foo, nach denen ich sortiere. Die Sortierungspriorität jedes Feldes hängt vom Kontext ab. Ich möchte so etwas schreiben:

int SortFunc<T> (Foo foo1, Foo foo2, params Func<Foo, T> [] selectors) 
    where T : IComparable<T> 
{ 
    return selectors 
     .Select (s => s (foo1).CompareTo (s (foo2))) 
     .FirstOrDefault (i => i != 0); 
} 

// Compare by SomeString, then by SomeInt, then by SomeBar 
int SomeSortFunc (Foo foo1, Foo foo2) 
{ 
    // Won't compile, because String, Int, and Bar are all different types. 
    return SortFunc (foo1, foo2, f => f.SomeString, f => f.SomeInt, f => f.SomeBar); 
} 

Dies wird nicht kompilieren, weil die T in Func<Foo, T> für String unterscheidet, Int und Bar : IComparable<Bar> (mit anderen Worten, es gibt keine Möglichkeit, die T in lösen SortFunc<T>).

Gibt es eine Möglichkeit, diese Funktion so zu schreiben, dass jeder Selektor einen anderen Typ zurückgeben kann, solange jeder Typ SomeTypeIComparable<SomeType> implementiert?

Antwort

3

Ich würde es vereinfachen und akzeptieren nur eine Funktion, die eine nicht-generische IComparable zurückgibt. Jetzt können Sie Funktionen übergeben, die Primitive zurückgeben, ohne die Anzahl der generischen Typparameter herausfinden zu müssen, die Ihre Funktion tatsächlich benötigen würde, da sie wahrhaftig Typparameter für jede der bereitgestellten Funktionen benötigen würde.

int SortFunc(Foo foo1, Foo foo2, params Func<Foo, IComparable>[] selectors) 
+0

Ah, das macht sehr viel Sinn und scheint perfekt zu funktionieren. Ich verliere ein bisschen Typsicherheit, aber es ist es definitiv wert. –

Verwandte Themen