- PR -

ジェネリック定義のパラメータを実行時に決定したい。

1
投稿者投稿内容
いのつち
ベテラン
会議室デビュー日: 2002/05/14
投稿数: 73
投稿日時: 2006-02-01 22:26
VS2005C# Expressでいろいろ試しています。
ジェネリックについて試しているのですが、実行時に定義したいのです。
(すみません用語が正しいかどうか自信がありません。。)

コード:
// このようなクラスがあって
class Validator<T> : IValidator { }

string typeString = "System.Int16"; //この型の名称はいろいろ変化

Type tp = Type.GetType("Validator`1[System.Int32]");
 // ここは、これでもいいけど。
 // Validator<int> dammy = new Validator<int>();
  // Type tp = dammy.GetType();

Type genericType = tp.GetGenericTypeDefinition();

Type paramType = Type.GetType(typeString); 

Type targetType = genericType.MakeGenericType(paramType);
IValidator vv = (IValidator) Activator.CreateInstance(targetType);



一応目的はこのコードで果たせたのですが、もっとスマートにならないものでしょうか。まだヘルプを読みきれていないのは否めません。

ダミーで、パラメータをセットした型を用意してからでないといけないところが
とても違和感を感じるのですが。。

Type tp = Type.GetType("Validator`1[System.Int32]");
ここのところは、省略して

Type genericType = Type.GetType("Validator`1[]");
なんてこともしたのですが、GenericTypeDefinitionでないと怒られてしまいます。
Type型としてはnull ではなく取得できているのですが。。。



ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2006-02-01 22:43
コード:


Type genericType = typeof(Validator<>);
Type intBindedType = typeof(Validator<int>);
Type genericType = Type.GetType("Validator`1");



こういうこと?
ジェネリックタイプの型名なら後ろの[]が余計です。

[ メッセージ編集済み 編集者: ya 編集日時 2006-02-01 22:45 ]
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-02-02 00:27
引用:

いのつちさんの書き込み (2006-02-01 22:26) より:
VS2005C# Expressでいろいろ試しています。
ジェネリックについて試しているのですが、実行時に定義したいのです。
(すみません用語が正しいかどうか自信がありません。。)


推測ですが、多分そんな機能はありません。

Genericを使用するメリットは、コンパイル時に型が確定するため、コンパイラの型チェック機能によりエラーを検出できることにあります。またコンパイラは型を知っているので、メンバの呼出において逐一キャストする必要がありません。BOX化を伴わずに値を格納することも出来ます。これらは全てコンパイル時に型が決定しているからこそ得られるメリットです。

実行時に型を決定するのであれば、それは.NET 2003以前からあるobject型を使った格納方法とまったく遜色ありません。あえてgenericにする必要は無いでしょう。

また現実的には、実行時まで型がまったく決定しないと言うことは無いでしょう。それらは大抵の場合何らかのクラス(インターフェース)を継承しているのではないですか?だとしたら継承もとのクラスを使ったgenericを使用すればすむ話で、実行時まで決定する必要は無いはずです。
いのつち
ベテラン
会議室デビュー日: 2002/05/14
投稿数: 73
投稿日時: 2006-02-02 21:26
甕星さん、yaさん ご返答ありがとうございます。
引用:

コード:
Type genericType = typeof(Validator<>);
Type genericType = Type.GetType("Validator`1");





コードはこれでいけました。ありがとうございます。[]が不要だったのですね。
typeof(Validator<>); これでもOKだったんですね。

 

引用:

実行時に型を決定するのであれば、それは.NET 2003以前からあるobject型を使った格納方法とまったく遜色ありません。あえてgenericにする必要は無いでしょう。



やっぱり使い方が正しくないですかね。Genericがどのようなものか、勉強しながら作ってみているのですが、試していたのは、テーブルのスキーマ設定ツールのようなもので、型によるチェックロジックをユーザが定義した値型をもとに処理するというものを想定しています。

確かにおっしゃる通り、インターフェイス経由でないと使えないので、クラス内部の処理部分ばかりがパラメータ型で、外部とのインターフェイスはobject型という扱いとなってしまい、設計がおかしいかなとは感じていたのですが^^;

発想が継承関係のようなイメージで作ったのが、そもそもの使用方法の誤りなんですよね^^;
ありがとうございます。





1

スキルアップ/キャリアアップ(JOB@IT)