我需要创建一个非常有效且重复的Action:
我的理解是构建表达式树并存储动作以便重用是最快的方法。我遇到了很多麻烦。为了使这一点更清楚,我需要一个表达式树编译动作来执行此操作:
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 :(得分:4)
无法有效地创建 非反射代码
private void AddToCollection(Type itemType, object item, object collection)
{
// Assume that itemType became T somehow
((ICollection<T>)collection).Add((T)item);
}
因为为了避免反射,必须事先知道Type
(具体或泛型类型参数)。
虽然可以创建这样的东西:
static Action<object, object> CreateAddToCollectionAction(Type itemType)
{
// Assume that itemType became T somehow
return (item, collection) => ((ICollection<T>)collection).Add((T)item);
}
以下是:
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();
}
样本用法:
var add = CreateAddToCollectionAction(typeof(int));
object items = new List<int>();
add(1, items);
add(2, items);