2011-10-15 19 views
5

タイプList<*DynamicType*>の動的変数のCapacityプロパティを変更する必要があります。 変数の型が適切なList<*DynamicType*>の代わりに指定されており、私ができる最善をIListにキャストすることですされていない場合、問題はそのActivator戻りobject -casted変数です:動的タイプの変数の汎用リストへのキャスト

DynamicTypeBuilder builder = new DynamicTypeBuilder() { ... }; 
Type dataType = builder.GenerateType(...); 
Type listDataType = typeof(List<>).MakeGenericType(dataType); 
IList list = (IList)Activator.CreateInstance(listDataType); 

いくつかの検索後、私は唯一のハックを見つけました:

dynamic dynamicList = list; 
dynamicList.Capacity = dataRowsCount; 

これは別の方法があるのでしょうか?

答えて

3

は、おそらくこれは簡単です:

正しいコンストラクタを使用する必要があります
object list = Activator.CreateInstance(listDataType, 
    new object[]{dataRowsCount}); 

ジェネリックとリフレクションは、実際には痛みです。 dynamicハックは、リフレクション(リテラルとしてのマジック文字列、未検証のプロパティメンバ)を設定するのは面倒ではなく、dynamicは内部的に最適化されキャッシュされているので、問題はありません。あなただけの1つのプロパティ以上のことを行う必要がある場合は、醜いを最小限に抑えるために、一般的な方法に反転させるdynamicを使用することができます:正しいTとジェネリックメソッドを呼び出します

void Evil<T>(List<T> list, int capacity) { 
    list.Capacity = capacity; 
    // do other stuff 
} 
... 
dynamic list = Activator.CreateInstance(listDataType); 
Evil(list, dataRowsCount); 

を。 1人のメンバーだけではそれほど価値はありませんが、より複雑なシナリオでは役立つかもしれません。

+0

そのコンストラクタを忘れてしまった。そのプロパティだけを設定する必要があるので、このようにするのは本当に簡単です。また、IListオブジェクトを「キャスト」するための汎用メソッドを使用することをお勧めします。 –

+0

私は何か間違っているかもしれませんが、 'Activator.CreateInstance()'の結果を 'generic'変数に代入すると動作しません。なぜなら、' list.Add(* Dynamically created dataType object *) '結果は例外的になり、 'list'を' IList'にプリキャストすることで動作します。 –

+0

@Dmitry、それから 'IList'にキャストしてください。この例では、例では*を実行するための最小値を示していたため、例には「Add(...)」がありませんでした。 –

4

あなたは反射でそれを行うことができます。

var capacityProperty = listDataType.GetProperty("Capacity"); 
capacityProperty.SetValue(list, dataRowsCount, null); 

代替は静的型付け方法であなたが望むすべてを行い、一般的なメソッドを記述し、代わりに反射してことを呼び出すことです。それはあなたがただ一つのリフレクションを必要としていることを確認する便利な方法です。

+0

いいえ、何らかの理由で反射について考えなかった。私は動的\ジェネリックをもう一度扱うときにこれを覚えています。 –

関連する問題