Traverse a Linq Expression to set the value of a property field

*爱你&永不变心* 提交于 2019-12-12 17:07:14

问题


This is a very complicated question even though it looks simple. I think I would have to traverse the entire expression tree unless someone knows a better way.

Let's say I have a user object

class User
{
    public UserAccount Account {get;set;}
}
class UserAccount
{
    public Name {get;set;}
}
var user = new User() { Account = new UserAccount()};

How could I use linq expressions to set the property of Name

SetValue(c => c.Account.Name, "Test");

回答1:


Well, you'd not only have to traverse the expression tree: you'd also have to convert final property "getter" you encounter into a property "setter". Essentially you'd want to find the expression which acts as the "target" of the getter (i.e. the object it's going to get the property of), evaluate it to get the target, then find the corresponding setter for the final property, and call it with the target and the new value.

Note that by only requiring the expression tree to represent the "getter", you're losing some of the compile-time safety you might expect... because a caller could pass in a read-only property:

SetValue(c => c.Account.Name.Length, 0); // string.Length is read-only

Another alternative would be to change your code to make the lambda expression represent the setter instead:

SetValue((c, value) => c.Account.Name = value, "Test");

Then you wouldn't even need an expression tree - you could use a simple delegate, and just execute it appropriately.

Unfortunately you haven't really given us enough information about what you're trying to achieve to know whether this is a feasible suggestion.




回答2:


Yes, you will have to traverse the whole expression tree which if you want to work in the general case might be challenging. Can't you just do this instead:

SetValue<User>(c => c.Account.Name = "Test");

Where SetValue is defined like this:

public void SetValue<T>(Action<T> action)
{
    ...
}

Or without the generic parameter if this will work only with User.



来源:https://stackoverflow.com/questions/3624313/traverse-a-linq-expression-to-set-the-value-of-a-property-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!