だらだらやるよ。

こげつのIT技術メモ

ジェネリック

地味だけど便利!あるとないとじゃ勝手が違う!

まずは今までのやり方

ArrayList al = new ArrayList();
al.add("testです。");
al.add(200);
string st = (string)al[0];
Console.WriteLine(st);
string st2 = (string)al[1];//実行時例外が発生する。
Console.WriteLine(st2);

で、ジェネリッククラスの使い方

List<string> list = new List<string>();
list.add("testです。");
//list.add(200);//コンパイルエラーがでるので記述不可
string st = list[0];
Console.WriteLine(st);

<>でくくった部分に型名を入れてやることにより、使用時に型を指定したコードを書くことができます。
javaにはありましたよね、ジェネリック
個人的にはとても便利だなぁと思います:-)

で、自分でジェネリックなクラスを作る方法

class TestClass<T> {
	T _val = default(T);

	public T Val {
		get { return _val; }
		set { _val = value; }
	}
	public TestClass(T val) {
		_val = val;
	}
	
	public string GetHelloHogeHoge(T word) {
		return "HelloHogeHoge" + word.ToString();
	}
}

簡単に言うとあれですね、オブジェクト型のかわりに<>で指定した型を使うイメージですねー<>の中の文字は任意の文字列でいいんのですが、特に何も無い場合Tを使うことが多いようです。
ちなみに2行目のdefault(T)ってのは、初期値の代入です。
それぞれの型の初期値が自動に入ります。(クラスはNULL、値型はそれぞれの初期値)

また型を制限することもできます。こんな感じ。

class Test1<T> where T : class{}//Tはクラスしか駄目。
class Test1<T> where T : struct{}//Tは構造体しか駄目。
class Test1<T> where T : new(){}//Tはインスタンス化可能じゃないと駄目。
class Test1<T> where T : MyClassName{}//TはMyClassを継承していないと駄目。
class Test1<T> where T : IMyInterfaceName{}//TはIMyInterfaceを使用していないと駄目。

継承もとのクラス指定は便利ですねー
Factoryのときとかに使用しやすいかなぁ?

で、ジェネリックはメソッドだけでも使えます。
記述方法はこんな感じ。

class TestClass2 {
	public TestClass2() { }
	public void Test<T>(T ob) {
	}
}

ジェネリックでもう一個
ジェネリックデリゲートについては匿名メソッドを紹介してからにしますね。