I'm trying to speed up reflection -> SetValue
with a LINQ expression.
My problem is this method:
public void SetValue<T>(T obj)
{
FieldInfo field = typeof(T).GetField("Title", BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.IgnoreCase);
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
ParameterExpression valueExp = Expression.Parameter(field.FieldType, "value");
// Expression.Property can be used here as well
MemberExpression fieldExp = Expression.Field(targetExp, field);
BinaryExpression assignExp = Expression.Assign(fieldExp, valueExp);
var setter = Expression.Lambda<Action<T, string>>(assignExp, targetExp, valueExp).Compile();
setter(obj, "Hello World");
//Console.WriteLine(obj.title);
}
which I call like this:
var ii = new Controllers.SearchController.InstantItem();
SetValue<Controllers.SearchController.InstantItem>(ii);
The problem is this line:
var setter = Expression.Lambda<Action<T, string>>(assignExp, targetExp, valueExp).Compile();
Because Action uses generics, I cannot replace string with field.FieldType
...
Is there any possibility I can do this without having to make a switch(field.FieldType)
statement, and put a generic method for each possible type, which would suck big time?
Maybe something like this
action = FormAction(fieldInfo);
action(obj,valueToSet);
Of course caching the Actions in a dictionary will be needed.
static Action<object, object> FormAction(FieldInfo fieldInfo)
{
ParameterExpression obj = Expression.Parameter(typeof(object), fieldInfo.Name);
ParameterExpression value = Expression.Parameter(typeof(object));
MemberExpression fieldExp = Expression.Field(Expression.Convert(obj, fieldInfo.DeclaringType), fieldInfo.Name);
BinaryExpression assignExp = Expression.Assign(fieldExp, Expression.Convert(value, fieldInfo.FieldType));
return Expression.Lambda<Action<object, object>>(assignExp, obj, value).Compile();
}