我尝试用表达树玩一下。
我有一个List<string>
的对象,我想构建一个向该属性添加值的表达式树,但我想指定要通过Func
添加的值。
目前我试试这个...
public static Action<T> CreateMethodAddObjectToList<T, C>(this Type type, string property, Func<C> ctorFunction)
{
PropertyInfo fieldInfo = type.GetProperty(property);
if (fieldInfo == null)
{
return null;
}
ParameterExpression targetExp = Expression.Parameter(type, "target");
MemberExpression fieldExp = Expression.Property(targetExp, property);
var method = fieldExp.Type.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);
Expression<Func<C>> ctorExpression = () => ctorFunction();
// but this doesnt work because I can't use the ctorExpression in this way
var callExp = Expression.Call(fieldExp, method, ctorExpression);
var function = Expression.Lambda<Action<T>>(callExp, targetExp).Compile();
return function;
}
电话看起来像
var dummyObject = new DummyObject { IntProperty = 5 };
Action<DummyObject> setter = typeof (DummyObject).CreateMethodAddObjectToList<DummyObject, string>("StringList", () => "Test" );
答案 0 :(得分:1)
您可以将ctorFunction更改为Expression<Func<C>>
,然后在生成的操作中调用它:
public static Action<T> CreateMethodAddObjectToList<T, C>(this Type type, string property, Expression<Func<C>> createExpr)
{
PropertyInfo fieldInfo = type.GetProperty(property);
if (fieldInfo == null)
{
return null;
}
ParameterExpression targetExp = Expression.Parameter(type, "target");
MemberExpression fieldExp = Expression.Property(targetExp, property);
var method = fieldExp.Type.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);
var valueExpr = Expression.Invoke(createExpr);
var callExpr = Expression.Call(fieldExp, method, valueExpr);
var function = Expression.Lambda<Action<T>>(callExpr, targetExp).Compile();
return function;
}