2017-06-20 7 views
1

を追加します。式ツリーキャスト&Iはなり非常に効率的にかつ繰り返しアクションを作成する必要が

  1. 変数は、オブジェクト型をキャストいるICollection型にオブジェクト型の変数をキャスト変数をT型変数に変更する
  2. ICollection型コレクションにT型アイテムを追加します。

表現ツリーを構築し、再利用のためのアクションを保存することがこれを行う最も簡単な方法です。私はそれに多くの問題を抱えています。それは

private void AddToCollection(Type itemType, object item, object collection) 
{ 
    // Assume that itemType became T somehow 
    ((ICollection<T>)collection).Add((T)item); 
} 

を行い効率的無反射コードを作成することはできません

private void AddToCollection(Type itemType, object item, object collection) 
{ 
    // assume itemType is used in the expression-tree to cast to ICollection<T> 
    ((ICollection<T>)collection).Add((T)item); 
} 
+0

はなぜだけではなく、汎用的な機能を使用します。

static Action<object, object> CreateAddToCollectionAction(Type itemType) { var item = Expression.Parameter(typeof(object), "item"); var collection = Expression.Parameter(typeof(object), "collection"); var body = Expression.Call( Expression.Convert(collection, typeof(ICollection<>).MakeGenericType(itemType)), "Add", Type.EmptyTypes, Expression.Convert(item, itemType) ); var lambda = Expression.Lambda<Action<object, object>>(body, item, collection); return lambda.Compile(); } 

使用例:ここでは

static Action<object, object> CreateAddToCollectionAction(Type itemType) { // Assume that itemType became T somehow return (item, collection) => ((ICollection<T>)collection).Add((T)item); } 

がどのようである:

は何かかわらず可能であることは、このようなものを作成するのですか?表現を使って何が得られるのですか? – Amy

+0

'Type itemType'引数では不可能です。特定の 'Type'に対して' Action 'を作成し、' object item、object collection'を複数回呼び出すことだけが可能です。それはあなたのために働くのですか? –

+0

@Amyタイプ引数を持たないため、汎用メソッドを使用できません。私は既に、属性でマークされたプロパティからのリフレクションを使用して、コレクションのインスタンスを導き出しました。 – Wilshire

答えて

3

:これは、もう少し明確にするために、私はこれを行うだろう表現ツリーコンパイルアクションを必要とします反射を避けるために、Typeを事前に(具体的またはジェネリック型の引数のどちらかで)知っていなければならないからです。

var add = CreateAddToCollectionAction(typeof(int)); 
object items = new List<int>(); 
add(1, items); 
add(2, items); 
関連する問題