使用表达式树设置字段值

时间:2016-05-12 13:47:52

标签: c# .net expression-trees

我需要为类中的所有字段创建一个表达式。 所以我已经根据我的需要采用了this post

public static void Sample()
{
    var setters = GetFieldSetterExpressions<Account>();
    var myAccount = new Account();
    setters["AccounHolder"](myAccount, "Giovanni");
    setters["Pin"](myAccount, 123);
}

public static Dictionary<string, Action<T, object>> GetFieldSetterExpressions<T>() where T: class 
{

    var dic = new Dictionary<string,Action<T,object>>();

    var type = typeof(T);
    var fields = type.GetFields();
    foreach (var fieldInfo in fields)
    {
        Type fieldType;

        if (IsNullableType(fieldInfo.FieldType))
            fieldType = Nullable.GetUnderlyingType(fieldInfo.FieldType);
        else
            fieldType = fieldInfo.FieldType;


        ParameterExpression targetExp = Expression.Parameter(type, "target");
        ParameterExpression valueExp = Expression.Parameter(fieldType, "value");

        MemberExpression fieldExp = Expression.Field(targetExp, fieldInfo);
        BinaryExpression assingExp = Expression.Assign(fieldExp, valueExp);

        var setter = Expression.Lambda<Action<T, object>>(assingExp, targetExp, valueExp).Compile();

        dic.Add(fieldInfo.Name, setter);
    }

    return dic;
}

我的问题是Expression.Lambda<Action<T,object>>(..),因为该字段可以是例如字符串,我得到一个例外。 我试图在我的代码段中对Expression.Convert进行整理,但无法弄清楚如何实现它。

如何在代码中集成转换部分?

1 个答案:

答案 0 :(得分:3)

Expression<Action<T, object>>表示第二个参数的类型为object,而您的代码使用propertyType。这是应该如何:

var type = typeof(T);
var fields = type.GetFields();
foreach (var fieldInfo in fields)
{
    var targetExp = Expression.Parameter(type, "target");
    var valueExp = Expression.Parameter(typeof(object), "value");

    var fieldExp = Expression.Field(targetExp, fieldInfo);
    var assignExp = Expression.Assign(fieldExp, Expression.Convert(valueExp, fieldExp.Type));

    var setter = Expression.Lambda<Action<T, object>>(assignExp, targetExp, valueExp).Compile();

}