4

そのクラスClass name as a stringのジェネリックを作成したいだけのシナリオがあります。List私は次のことを試しました

            Type _type = Type.GetType(className);

            List<_type> list = new List<_type>();

しかし、私は得てerrorいます。その _type をリスト引数として指定することはできません。誰かが知っているなら、私を助けてください

4

4 に答える 4

11

あなたが得ることができる最も近い:

Type listType = typeof(List<>).MakeGenericType(_type);
IList list = (IList) Activator.CreateInstance(listType);
于 2012-07-16T17:52:15.190 に答える
2

オブジェクトのタイプは実行中のプログラムによって任意に変更される可能性があるため、リフレクションは実行時に行われます。

一方、型パラメーター(ジェネリック)は、型の安全性をチェックするためにコンパイラーによってのみ使用されます。

したがって、コンパイラはリフレクションの結果について何も知らないため、リフレクションを使用して型パラメータを指定することはできません。

于 2012-07-16T17:50:41.977 に答える
1

.Net 4 を使用している場合は、使用するとdynamic役立つ場合があります。この場合、非ジェネリック インターフェイス ( など) を介してアクセスできないインスタンスでメソッドを使用できますIList

たとえば、 を使用すると、リストdynamicのメソッドを呼び出すことがAddRangesできますが、これは へのキャストでは実行できませんでしたIList:

Type _type = typeof(int);
Type listType = typeof(List<>).MakeGenericType(_type); 
dynamic list = Activator.CreateInstance(listType); 

list.Add(1);   
list.AddRange(new int[] {0, 1, 2, 3});  

ただし、このメソッドは、コンパイル時にエラーをキャッチできないため、非ジェネリック インターフェイスへのキャストほどタイプ セーフではありません。

于 2012-07-16T20:33:03.397 に答える
0

残念ながら、ジェネリックはコンパイル時に認識される必要があるため、これは不可能です。実行時に通知することで、これを再定義しようとしています。コンパイル時にそれらを知る必要がある理由は、コンパイラーが、渡されたすべての変数が有効であることを検証できるようにするためです。AFAIK、あなたが行きたいことをすることはジェネリックの完全な書き直しを必要とするでしょう。

コンパイル時チェックの背後にある主な理由は、実行時に変更される可能性があり、JITコンパイラが型チェックを行う必要があるため_type、に追加する際にオーバーヘッドが発生することです。List<T>

@MarkusJarderotが言ったことは、ジェネリックの代わりにインターフェースが使用されるため、取得できる最も近いものです。

于 2012-07-16T17:50:06.890 に答える