事の起こりは、ジェネリックの「SortedDictionary」クラスを使おうと思ったこと。
デフォルトの比較ルールだと、希望する順番にソートされないので、比較関数を置き変えたかった。そのためにはどうするのか?MSDNを引いてみると、
SortedDictionaryのコンストラクタのオーバーロードを確認しても、IComparer<TKey>を指定するものはあっても、Comparison<TKey>を指定できるものはない。えー?このためにクラス一個作んないとダメってことかい?めんどくせ。
List<T>とかのSortメソッドには、Comparison<T>もIComparer<T>もどっちも引き渡せるようになっているのに…。.net 2.0の時代ならいざ知らず…、ちょっと片手落ちじゃないすか?というか、手を入れ損なったのかなぁ。
ま、無いものはしょうがない。とはいえ、クラスを作るにしても似たようなものを何度も作りたくはない。なので、『Comparison<T> デリゲートを利用した IComparer<T> の実装クラス』を作り、汎用的に使いまわせるようにしようと考えた次第。
しかし、ここで悩んだのはそのクラス名。汎用的なIComparer実装クラスなので、「Comparer」クラスにしたかったのだけど、「System.Coolection.Generic.Comparer」クラスが既に存在しているので却下。
悩んだ挙句、「ComparisonComparer<T>」にしました。頭痛が痛いような名前。でもまぁ、名は体を表していることには違いないし、なによりIntellisenceで「Compar...」でリストアップされるので、まぁ、使い勝手は悪くないんじゃないかと思う。
およそ実装はこんな感じ。
class ComparisonComparer<T> : IComparer<T> { private Comparison<T> comparison; public ComparisonComparer(Comparison<T> comparison) { this.comparison = comparison; } public int Compare(T p1, T p2) { return comparison(p1, p2); } }
念のため、ジェネリックじゃないIComparerも実装しておいたほうがいいかも。そして、こう使うと。
var dic = new SortedDictionary<string, int>( new ComparisonComparer<string>((p1, p2) => string.Compare(p1, p2)));
正直、それほど使い道があるわけじゃない(ざっと見た限り、SortedListやSortedSetではIComparer<T>が必要なので、使い道はありそうだけど、それくらい…)。だけど、いちいちクラス一個作るよりはいいでしょ。
0 件のコメント:
コメントを投稿