2016-05-12 30 views
3

我需要爲類中的所有字段創建表達式。 所以我採用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>>(..)領域例如可以是字符串,我得到一個exeption。 我試圖在我的代碼片段中整合Expression.Convert,但無法弄清楚如何實現它。

我如何需要將轉換部分集成到我的代碼中?

+0

你可以顯示你正在嘗試構建的整個方法(包括簽名)嗎? –

+0

@IvanStoev更新代碼:基本上(簡化)我想要做的事情。感謝您的支持。 – gsharp

+0

我明白了。那麼答案應該適用於你,我會刪除第一句話。 –

回答

2

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(); 

}