2010-12-20 5 views
0

私は2つの行を比較する関数を渡すことでソートすることができるライブラリ(GtkのTreeViewは具体的です)を使って作業しています。関数のシグネチャの簡易版は、次のようになります。この汎用メソッドをより柔軟にするにはどうすればよいですか?

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

私は状況に応じて異なるソートしたいので、私は単純に、Foo.CompareTo (Foo)を実装することはできません。 Fooには、私が並べ替えるいくつかのフィールドがあります。各フィールドのソート優先度は、コンテキストに依存します。私はこのような何か書きたいと思います:Func<Foo, T>Tは、言い換えればStringInt、およびBar : IComparable<Bar>(異なるため、

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

これはコンパイルされませんが、T内を解決する方法はありませんSortFunc<T>)。

SomeTypeIComparable<SomeType>を実装している限り、各セレクタが異なる型を返すようにこの関数を書く方法はありますか?

答えて

3

私はそれを簡略化し、非汎用のIComparableを返す関数を受け入れるだけです。実際に必要なジェネリック型のパラメータの数を把握することなく、プリミティブを返す関数を渡すことができるようになりました。

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

ああ、それはかなり意味があり、完璧に動作しているようです。私は型の安全性を少し失うが、それは間違いなく価値がある。 –

関連する問題