2017-09-22 67 views
0

如何使用Expression在已有對象的實例上設置屬性?我不想創建一個新的對象,所以Expression.New你可以在成員初始化器中傳遞將不起作用。用於在現有對象實例上設置屬性的表達式

這不是How to set property value using Expressions?的副本,因爲這需要Expression並通過Reflection設置屬性。

我有一個現有的object並且想創建一個Expression我可以在其中設置屬性。然後將該表達式編譯成delegate執行。

+0

可能重複的[如何使用表達式設置屬性值?](https://stackoverflow.com/questions/9601707/how-to-set-property-value-using-expressions) –

+2

Expression.Assign into Expression。你的對象的屬性(作爲一個ConstantExpression或ParameterExpression取決於你如何使用它)傳遞你想分配的屬性的PropertyInfo – pinkfloydx33

回答

1

怎麼樣:

public class User { 
    public string Name {get;set;} 
} 

public static void Main() 
{ 
    var user = new User(); 
    var assigner = GetAssigner<User, string>(u => u.Name); 
    assigner.Compile()(user, "Joe"); 
    Console.WriteLine(user.Name); 
} 

public static Expression<Action<TClass, TValue>> GetAssigner<TClass, TValue>(Expression<Func<TClass, TValue>> propertyAccessor){ 
    var prop = ((MemberExpression)propertyAccessor.Body).Member; 
    var typeParam = Expression.Parameter(typeof(TClass)); 
    var valueParam = Expression.Parameter(typeof(TValue)); 
    return Expression.Lambda<Action<TClass, TValue>>(
     Expression.Assign(
      Expression.MakeMemberAccess(typeParam, prop), 
      valueParam), typeParam, valueParam); 

} 

記住的表達僅僅是一個應該做些什麼定義,你必須把它編譯成一個代表到能夠調用它。

+0

「Expression.Assign」與「Expression.MakeMemberAccess」的組合恰恰是我在尋找。 –

1

你看過使用MemberAssignment來設置成員的值嗎?

表示對對象字段或屬性的賦值操作。

但是,備註中的重要注意事項:不能直接創建這些。相反,

使用Bind工廠方法創建MemberAssignment。 MemberAssignment的BindingType屬性等於Assignment

+0

我有一個'MemberAssignment'列表。如何創建一個'表達式'來將它們分配給一個現有的對象?我可以通過'Expression.New'創建一個新對象,但我不知道如何用現有的對象來完成它。 –

+0

這已經有一段時間了,但我似乎記得'MemberAssignment'專門用於對象初始化表達式,比如'new X {Member = y}'。一個普通的舊的'分配(屬性(x,「成員」),y)'應該沒問題。 –

+0

文檔沒有提到對象初始化表達式,也許你正在考慮[MemberInitExpression](https://msdn.microsoft.com/en-us/library/system.linq.expressions.memberinitexpression(v = vs.110) )的.aspx)? –

相關問題