私は、インデクサーを使用する方法についての完全な例を投稿します:
ParameterExpression dictExpr = Expression.Parameter(typeof(Dictionary<string, int>));
ParameterExpression keyExpr = Expression.Parameter(typeof(string));
ParameterExpression valueExpr = Expression.Parameter(typeof(int));
// Simple and direct. Should normally be enough
// PropertyInfo indexer = dictExpr.Type.GetProperty("Item");
// Alternative, note that we could even look for the type of parameters, if there are indexer overloads.
PropertyInfo indexer = (from p in dictExpr.Type.GetDefaultMembers().OfType<PropertyInfo>()
// This check is probably useless. You can't overload on return value in C#.
where p.PropertyType == typeof(int)
let q = p.GetIndexParameters()
// Here we can search for the exact overload. Length is the number of "parameters" of the indexer, and then we can check for their type.
where q.Length == 1 && q[0].ParameterType == typeof(string)
select p).Single();
IndexExpression indexExpr = Expression.Property(dictExpr, indexer, keyExpr);
BinaryExpression assign = Expression.Assign(indexExpr, valueExpr);
var lambdaSetter = Expression.Lambda<Action<Dictionary<string, int>, string, int>>(assign, dictExpr, keyExpr, valueExpr);
var lambdaGetter = Expression.Lambda<Func<Dictionary<string, int>, string, int>>(indexExpr, dictExpr, keyExpr);
var setter = lambdaSetter.Compile();
var getter = lambdaGetter.Compile();
var dict = new Dictionary<string, int>();
setter(dict, "MyKey", 2);
var value = getter(dict, "MyKey");
IndexExpression
が直接インデックス付きプロパティの値が含まれているインデクサから読み込むには。それに書き込むにはExpression.Assign
を使用する必要があります。他のすべてはかなりバニラExpression
です。 Danielによって書かれているように、Indexerは通常 "Item"と呼ばれています。 Expression.Property
にはインデクサーの名前を直接受け入れる過負荷があるので("Item"
)、手動で検索することにしました(再利用できるようにしました)。私はあなたが望むインデクサの正確なオーバーロードを見つけるためにLINQの使い方の例を書いています。
あなたがProperties下、Dictionaryのために例えばMSDNに見ればただの好奇心として、あなたはItem
*「通常」*、それがないときに見つけることができますか?どうやってそれを確実に得ることができますか? –
インデクサーの 'IndexerName'属性を使って変更できます。インデクサを含むクラスを反映させ、 'DefaultMember'属性を取得してインデクサプロパティの名前を確実に取得することができます。詳細については、[ここ](http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/60de101a-278d-4674-bc1a-0a04210d566c)を参照してください。 –
ありがとうございました。それは実際に動作します - Expression.Property(パラメータ、 "Item"、Expression.Constant(...)) – Ondra