{{indexmenu_n>21}} ====== generics ====== genericsはC++のテンプレートと同じようなものです。テンプレートの場合、型の解決は実際のコード中でそのテンプレートが利用されるときに行われますが、genericsではgenericを使ったクラスがあった場合、そのクラスを使うコードがなくてもコンパイルできなければなりません。実行時に動的にそのgenericsを利用可能にするためです。そのため以下のような問題があります。 以下のようなC++のテンプレートを考えます。 class C { public: int func() { return 1; } }; template class Caller { public: int DoFunc(T& t) { return t.func(); } }; int main() { C c; Caller caller; int i = caller.DoFunc(c); return 0; } これをC++/CLIのgenericsを使って書くと以下のようになり、コンパイルエラーとなります。 ref class C { public: int func() { return 1; } }; generic ref class Caller { public: int DoFunc(T t) { return t->func(); // error } }; int main() { C^ c = gcnew C; Caller^ caller = gcnew Caller; int i = caller->DoFunc(c); return 0; } 型Tはコンパイル時に解決しないため、Object型としかみなせないためです。そのためgenericsでは以下のような方法を利用します。 interface class I { int func(); }; ref class C : I { public: virtual int func() { return 1; } }; generic where T : I ref class Caller { public: int DoFunc(T t) { return t->func(); } }; int main() { C^ c = gcnew C; Caller^ caller = gcnew Caller; int i = caller->DoFunc(c); return 0; } インターフェースIを利用して、型Tに縛りをかけます。 その他の注意点として、genericの型はハンドルか値型でなければなりません。