私は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
は、言い換えればString
、Int
、および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>
)。
SomeType
がIComparable<SomeType>
を実装している限り、各セレクタが異なる型を返すようにこの関数を書く方法はありますか?
ああ、それはかなり意味があり、完璧に動作しているようです。私は型の安全性を少し失うが、それは間違いなく価値がある。 –