C#でジェネリックと型引数と型制約
ジェネリッククラスについて自分なりのまとめ。
List<T>
といった、任意の型を指定できるクラス。
型引数について
正確ではないけれど、型引数はジェネリッククラスの中でプレースホルダーのように使われるイメージ。
ジェネリッククラスを使う際に型引数に具体的な型を指定すると、クラス内の各型プレースホルダーにそれらの具体的なクラスが当てはめられる。
例えば、以下のようなジェネリッククラスを定義する。
//ジェネリックメソッド //二つの引数を入れ替えるだけ public static (T a, T b) MySwap<T>(T x, T y) //Tが型のプレースホルダーみたいなもの { return (y, x); }
これを呼び出し側で MySwap<string>("Hello1", "Hello2")
とする。型引数にはstring
を指定。
上記のジェネリックメソッドは以下のようにT
の部分にstring
が展開される。
public static (string a, string b) MySwap<string>(string x, string y) { return (y, x); }
型引数は複数指定可能
<>
には複数の型を指定できる。
public static (T2 a, T1 b) MySwap<T1, T2>(T1 x, T2 y) { return (y, x); }
型制約
型制約は、指定可能な型引数を制限するための仕組み。
インスタンス化可能であることとか、特定のインターフェースを実装していることとか、where
を使って規定できる。
例えばT1
はインスタンス化できるクラスでなければならないという制約をつけたい場合は、
public static (T2 a, T1 b) MySwap<T1, T2>(T1 x, T2 y) where T1:new() { return (y, x); }
T2
はIEnumerable<string>
を実装していなければならないのであれば、
public static (T2 a, T1 b) MySwap<T1, T2>(T1 x, T2 y) where T1:new() where T2:IEnumerable<string> { return (y, x); }
というように制約をつける。