这是一个非常复杂的问题,即使看起来很简单。我想我必须遍历整个表达式树,除非有人知道更好的方法。
假设我有一个用户对象
class User
{
public UserAccount Account {get;set;}
}
class UserAccount
{
public Name {get;set;}
}
var user = new User() { Account = new UserAccount()};
我如何使用linq表达式设置Name
的属性SetValue(c => c.Account.Name, "Test");
答案 0 :(得分:2)
好吧,你不仅需要遍历表达式树:你还必须将遇到的最终属性“getter”转换为属性“setter”。基本上你想要找到充当getter“目标”的表达式(即它将获取属性的对象),计算它以获取目标,然后为最终属性找到相应的setter,并且用目标和新值来称呼它。
请注意,只需要表达式树来表示“getter”,你就会失去一些你可能期望的编译时安全性......因为调用者可以传入一个只读属性:
SetValue(c => c.Account.Name.Length, 0); // string.Length is read-only
另一种方法是更改代码,使lambda表达式代表setter:
SetValue((c, value) => c.Account.Name = value, "Test");
然后你甚至不需要表达式树 - 你可以使用一个简单的委托,只需适当地执行它。
不幸的是,你并没有真正向我们提供足够的信息,告诉我们你想要了解的是否这是一个可行的建议。
答案 1 :(得分:1)
是的,您必须遍历整个表达式树,如果您想在一般情况下工作,可能会遇到挑战。你不能这样做:
SetValue<User>(c => c.Account.Name = "Test");
SetValue
的定义如下:
public void SetValue<T>(Action<T> action)
{
...
}
或者没有通用参数,如果这只适用于User
。