I need to create an Action that will very efficiently and repeatedly:
It's my understanding that building an expression tree and storing the action for reuse is the fastest way to do this. I'm having a lot of trouble with that. To make this a little more clear, I need an expression-tree-compiled-action that will do this:
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);
}
It's not possible to create efficiently non reflection code which does
private void AddToCollection(Type itemType, object item, object collection)
{
// Assume that itemType became T somehow
((ICollection<T>)collection).Add((T)item);
}
because in order to avoid the reflection, the Type
has to be known in advance (either concrete or generic type argument).
What is possible though is to create something like this:
static Action<object, object> CreateAddToCollectionAction(Type itemType)
{
// Assume that itemType became T somehow
return (item, collection) => ((ICollection<T>)collection).Add((T)item);
}
Here is how:
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();
}
Sample usage:
var add = CreateAddToCollectionAction(typeof(int));
object items = new List<int>();
add(1, items);
add(2, items);