R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

IEnumerable を使ってみる(その2)

http://blogs.wankuma.com/rti/archive/2007/04/06/70413.aspx
IEnumerable を使ってみる

上記にて、皆さんにいただいたコメントを読んで、元記事の表現がわかりにくく、しかも一部間違っていたことに気付きました。
単なる苦労話の日記というつもりで書いてしまったためだと思うのですが、技術文章として参考にする人がいた時に、逆に惑わせてしまう危険性もあるので、今回きちんとまとめなおすことにします。

前記事でコメントをいただいた方々、本当にすみませんでした。

<(_@_)>

さて、お詫びも済んだところで、僕がやりたかったことを書きます。
以下、C# のコードです。


public class あいてむ {
  public string 名前;
  // その他、いろいろなメンバ
}


上記のオブジェクトのコレクションクラスを作る場合です。
コレクションクラスを作るとは言いましても、これが主体ということではなく、コレクションクラスとしても動作するクラスと言う方が正しいでしょうか(要するに、基本クラスが既にある訳です)

従って、核となるコレクションクラスをラッピングしなければならないので、IEnumerable インターフェイスを実装して、外部からの foreach に対応させる必要が生じます。


public class あいてむコレクション : 基本クラス, IEnumerable
{
  Dictionary dic = new Dictionary();

  public IEnumerator GetEnumerator() {
    return this.dic.Values.GetEnumerator();
  }

  public あいてむ this[string index] {
    get {
      return this.dic[index];
    }
  }

  public void Add(あいてむ item) {
    this.dic.Add(item.名前, item);
  }

  public int Count() {
    return this.dic.Count;
  }
}


次のように foreach が使えるようになります。


あいてむコレクション c = this.GetItemCollection();
foreach (あいてむ i in c) {
  // ここで i オブジェクトに対する諸々の処理をする
}


改めて、前回の内容のわかりにくさに orz

投稿日時 : 2007年4月9日 15:37

Feedback

# re: IEnumerable を使ってみる(その2) 2007/04/09 16:36 まどか

#1Stepで書いてみよう(汗

Public class あいてむCollection
Inherits Generic.List(of あいてむ)
End Class

あ、本題はIEnumerableでした。m(_ _)m

# re: IEnumerable を使ってみる(その2) 2007/04/10 10:26 R・田中一郎

まどかさん

改めて、ジェネリックって便利だなー、と思いますね。

# re: IEnumerable を使ってみる(その2) 2007/04/11 20:34 渋木宏明(ひどり)

>コレクションクラスを作るとは言いましても、これが主体ということではなく、コレクションクラスとしても動作するクラスと言う方が正しいでしょうか(要するに、基本クラスが既にある訳です)

どういう場面でそんな必要性があるのか、想像がつきませんでした。
「基本クラス」=「あいてむクラス」 じゃないんですよね?

とある「基本クラス」が存在していて、それ自身がコレクションとしても動作する、なんて実装は標準クラスライブラリでも見かけたことがないです。

そんなクラスを作ったとして、そのクラスのとあるメソッドが「基本クラス」に作用するのか、コレクションに作用するのか分かりづらくないですか?

さらに言えば、さらに別のコレクションを追加したくなったらどん詰まりですよね?

とある「基本クラス」に「あいてむクラス」のコレクションを追加する場合は

class あいてむCollection : 後述
{
// 適宜
}

class 基本クラス
{
private あいてむCollection _Items = new あいてむCollection();

public あいてむCollection Items
{
get { return this._あいてむCollection; }
}

のように、まず「あいてむCollection」クラスを定義して、「基本クラス」に「あいてむCollection」型の「Items プロパティ」を増設する方が自然だし、「どん詰まり」も避けられると思います。

そして、これも好みなのかもしれませんが、IEnumerable を直接的に継承してコレクションクラスを作ることもしません。

アプリケーション内部での閉じた利用なら List<T>, Dictionary<K,V> といった出来合いのクラスを使うし、クラスライブラリとして公開するような場合は Collection<T> や KeyedCollection<K,V> などの「それ用」に用意された、より上位のクラスを使います。

# re: IEnumerable を使ってみる(その2) 2007/04/12 13:36 R・田中一郎

渋木宏明(ひどり) さん

>どういう場面でそんな必要性があるのか、想像がつきませんでした。

今回の場合は、カスタムコントロールです。
UserControl の派生クラスで、エントリーされるアイテムオブジェクトにアクセスするために、カスタムコントロール[index] のように記述させたくなったのです。

>とある「基本クラス」に「あいてむクラス」のコレクションを追加する場合は

>のように、まず「あいてむCollection」クラスを定義して、「基本クラス」に「あいてむCollection」型の「Items プロパティ」を増設する方が自然だし、「どん詰まり」も避けられると思います。

あ、これは面白いですね。
早速、使用してみたいと思います。

# re: IEnumerable を使ってみる(その2) 2007/04/13 19:44 渋木宏明(ひどり)

>カスタムコントロール[index] のように記述させたくなったのです。

それじゃあ「カスタムコントロールの配列」があるみたいに見えちゃわないっすか?

# re: IEnumerable を使ってみる(その2) 2007/04/13 20:03 R・田中一郎

渋木宏明(ひどり) さん

>それじゃあ「カスタムコントロールの配列」があるみたいに見えちゃわないっすか?

なるほど、確かにそれは言えていますね。

DataGridView grid = new DataGridView();
thig.grid[0, 0]・・・ という記述ができるので、これを真似てみたつもりだったのですが、あまり良い方法では無いのかもしれませんね。

# re: IEnumerable を使ってみる(その2) 2007/04/14 7:11 渋木宏明(ひどり)

>thig.grid[0, 0]・・・ という記述ができるので、

それはコレクションじゃなくて、インデクサ ;-p
grid.Add(x,y,item) とか出来ないでしょ?

# re: IEnumerable を使ってみる(その2) 2007/04/16 10:19 R・田中一郎

渋木宏明(ひどり) さん

>それはコレクションじゃなくて、インデクサ ;-p

コントロール[index] という表現ができることが、「配列があるように見えるから良くない」という意味なのだと認識しているのですが、違うのかな?

何か、良くわかっていなくてすみません。

# re: IEnumerable を使ってみる(その2) 2007/04/16 13:33 渋木宏明(ひどり)

「インデクサ」が何かくらいは調べてみてくださいな。

DataGridView で grid[x,y] = xxx みたいな記述が出来るのは、DataGridView が「コントロールであり、はたまたコレクションでもある」からではなく、DataGridView が「インデクサ」を実装してているからです。

なので「DataGridView を真似てみるつもり」で「自前のクラスに ICollection の実装を追加」したのは見当違いつーことです。

DataGridView クラスは ICollection や他のコレクション系のインターフェースを継承してもいないし。

# re: IEnumerable を使ってみる(その2) 2007/04/17 14:36 R・田中一郎

渋木宏明(ひどり) さん

言われてみると確かにそうですね。
僕は、未だに混同しています。
両方とも実際に使っているのですが、仰られるように、一度きちんと違いを知らないと駄目ですね。

タイトル
名前
Url
コメント