情報科学屋さんを目指す人のメモ(FC2ブログ版)

何かのやり方や、問題の解決方法をどんどんメモするブログ。そんな大学院生の活動「キャッシュ」に誰かがヒットしてくれることを祈って。

ブログ内検索

スポンサーサイト このエントリーを含むはてなブックマーク

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

スポンサー広告 | 編集
このエントリーをはてなブックマークに追加 Clip to Evernote

SortedListと、ジェネリックス版SortedListにはまる このエントリーを含むはてなブックマーク

.NET Framework 2.0ジェネリクスが導入されたのですが、Javaに比べるとほんのちょっととっつきにくい感じがしていました。で、今回は、SortedListの非ジェネリクス版とジェネリクス版とにおける、Keyの比較方法の実装方法(形式)の違いについてです。(いつも通りメモなので、不完全です…)。「配列にある 2 つの要素を比較できませんでした。」というエラーが出てしまったら、これが原因・・・かも。


非ジェネリクス版とは、System.Collections.SortedList(以下、SortedList)のことで、ジェネリクス版System.Collections.Generic.SortedList<TKey, TValue> (C#風の書き方の場合、以下、SortedList) です。

非ジェネリクス版:System.Collections.SortedList
ジェネリクス版:System.Collections.Generic.SortedList<Tkey, TValue>




ここからは、.NET Framework の現在での最新版である.NET Framework 3.5 のMSDN ライブラリ を参考にしつつ、、現在 .NET Frameworkを利用するなら、ジェネリクス版(SortedList<TKey, TValue>)を利用した方がいいと言うことを前提にします。扱いやすいですし。


以下本題。

目的は、SortedList<TKey, TValue>に自作のクラスDataClassのインスタンスを格納しようということです。

SortedList<TKey, TValue>に、DataClassのインスタンスを入れようとするのですから、普通DataClassは順序づけができる(比較ができる)はず(Sortしたいから)なので、DataClassにIComparableインターフェースを実装して、IComparableインターフェースのCompareTo(object obj)が実装可能なはずです。

そして、SortedList<TKey, TValue>をここではSortedList<DataClass, DataClass>として、new SortedList<DataClass, DataClass>()で作ったインスタンスを作ります。
// DataClass : IComparable
SortedList<DataClass, DataClass> dataList;
dataList = new SortedList<DataClass, DataClass>();

このdataListに追加したいオブジェクト(=data)をAddすればいいわけです。
// SortedList<TKey, TValue>.Add(TKey key, TValue value)
DataList d1 = new DataClass(1); // たとえば
DataList d2 = new DataClass(2);
dataList.Add(d1, d1);
dataList.Add(d2, d2);

これでいいんだと思ってました。しかし、これは非ジェネリクスのSortedListでの方法で、IComparableもSystem.Collectionsにあります。しかし、これでも、ちゃんと動いちゃうんです!互換かな?

じゃぁ、MSDN通りにするにはどうするかというと、IComparableにもジェネリクス版というか、ジェネリクス用にIComparer<T>があります。これを使えという訳です。

非ジェネリクス版:System.Collections.IComparable
ジェネリクス版:System.Collections.Generic.IComparer<T>


しかし、ほとんど同じだろうと思って使ってみると全然違うみたいです。

名前をよーく見ると、ICompar"er"なので、比較する道具、つまり、ものさしみたいなイメージですね。なので、実装するメソッドも、Compare(T x, T y)となっていて、2つのオブジェクトを外から比較するようになっています

じゃぁ、どうするのかと言いますと。実際にIComparerを実装したクラス(正直、DataClassでもいいんですけど)のインスタンスを作成して、この"ものさし"オブジェクトをSortedList<TKey, TValue>に登録してあげます。そうすると、その"ものさし"のCompareメソッドを利用して比較してくれるというわけです。この登録は、必ずSortedList<TKey, TValue>のコンストラクタの引数として設定してください。

// Monosashi<DataClass> : IComparer<DataClass>
Monosashi<DataClass> m = new Monosashi<DataClass>();
SortedList<DataClass, DataClass> list = new SortedList<DataClass, DataClass>(m);


なぜ、コンストラクタが必要なのかというと、SortedList<TKey, TValue>.Comparerは、読み取り専用プロパティだからです。後から設定し直すことができないからです





ふぅ、メモ完了。ポイントは、IComparerはIComparagleとは違って、"ものさし"なだけだから、ちゃんと"ものさし"専用オブジェクトを用意して、SortedList<TKey, TValue>のコンストラクタで指定しなければならないということです。似てるけど、違うんですね。


ちょっと宣伝。
Javaを始めたいという方は、このJavaの環境の作成の仕方ページを参考にしてみてください><

未分類 | コメント:2 | トラックバック:0 | 編集
このエントリーをはてなブックマークに追加 Clip to Evernote

この記事のコメント

ずっとこれではまってたんです・・・。
すっごく助かりましたm(_ _)m
2009-12-18 Fri 10:28 |  ぽち
> ずっとこれではまってたんです・・・。
> すっごく助かりましたm(_ _)m

ぽちさん、コメントありがとうございます。
記事の内容が役に立ったようで、とても嬉しいです^^
2009-12-19 Sat 00:01 |  でぃどでぃど

コメントの投稿 エントリの新旧に関わらず、極力18時間中に返信します。














この記事のトラックバック

トラックバックURL:
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。