ジェネリック

今回はジェネリック
一度では、ちょっとした勉強では、語りきれない機能。
そんな印象。
@ITでも以下のように、多数のページを割いて特集を組んでいるほど。
なので、今回はさわりだけでも、という思いでチャレンジしてみることにする。
 

連載:C# 2.0入門
第2回 ジェネリック
http://www.atmarkit.co.jp/fdotnet/csharp20/csharp20_02/csharp20_02_01.html

C#VBジェネリック超入門(前編)
ジェネリック・クラスで変わるC#VBのコレクション
http://www.atmarkit.co.jp/fdotnet/special/generics01/generics01_01.html

C#VBジェネリック超入門(後編)
ジェネリックなメソッドやデリゲートがもたらす新スタイル
http://www.atmarkit.co.jp/fdotnet/special/generics02/generics02_01.html

 
まず、ジェネリックという機能がどうして必要か、という部分。
コレです、と一つだけ理由を挙げるわけにはいかない。
が、共通して語られているのは、キャストの問題。
 
下記は ArrayList の例。
 

  System.Collections.ArrayList al = new System.Collections.ArrayList();
  al.Add(100);
  string str = (string)al[0];
  Console.WriteLine(str);

 
実行すると例外が起きた。
「型 'System.Int32' のオブジェクトを型 'System.String' にキャストできません。」
 
ArrayList は要素に何でも追加できる。
それは内部的に Object 型で持っているということであり、同時に、取り出しにはキャストが必要であることを指してしまう。
 
C#2.0 からは ArrayList クラスのジェネリック版 List クラスが用意されている。
もっと言えば、System.Collections 名前空間にあったコレクションクラスの多くが System.Collections.Generic 名前空間以下にジェネリック版として構築されている。
 
今度は List クラスの例。
 

  List<string> l = new List<string>();
  l.Add(100);
  string str = l[0];
  Console.WriteLine(str);

 
エラー 1:'System.Collections.Generic.List.Add(string)' に最も適しているオーバーロード メソッドには無効な引数がいくつか含まれています。
エラー 2:引数 '1': 'int' から 'string' に変換できません。
 
実行する前にコンパイルでエラーが出力された。
これはジェネリック・コレクションが型を指定しているため、コンパイル時に厳密な判断を行うことが出来ることによる恩恵。
もちろん正しい要素を与えれば問題なく実行できる。
 
もう一つのポイントは、キャストが不要なこと。
これも同様の理由で、不要となることがわかるだろう。
 
 
 
さて、ジェネリック・コレクションのさわりを紹介した。
実際にはこれだけの機能ではない。
 
コレクション以外にも、クラス・構造体・インターフェース・デリゲート・メソッドなど様々な対象に実装することが出来る。
記述的に何となく C++ の template 機能を思い出すが、実は私は STL(Standard Template Library) をあまり使ってこなかったので良く知らない。
学びたい学びたいと思ってるうちに、タイミングを逃したのだが、そんなことはどうでも良い。
今回こそはジェネリックをモノにしたいと思う次第。