C# 使用表达式树导航并返回拥有属性的对象
给定一个指向对象图中某个属性的表达式,我想用该图检索拥有该属性的实例。我一直在挣扎。当前代码只给了我System.InvalidOperationException:Lambda参数不在范围内C# 使用表达式树导航并返回拥有属性的对象,c#,.net-3.5,expression-trees,C#,.net 3.5,Expression Trees,给定一个指向对象图中某个属性的表达式,我想用该图检索拥有该属性的实例。我一直在挣扎。当前代码只给了我System.InvalidOperationException:Lambda参数不在范围内 [Test] public void TestExpression() { var person = new Person {Address = {Street = "Bank Street"}, Name = "Joe"}; Expression
[Test]
public void TestExpression()
{
var person = new Person {Address = {Street = "Bank Street"}, Name = "Joe"};
Expression<Func<Person, object>> exp = p => p.Address.Street;
Assert.AreEqual("Bank Street", exp.Compile().Invoke(person));
var owner = GetPropertyOwner(person, exp);
Assert.AreEqual(owner, person.Address);
}
private object GetPropertyOwner<T>(T root, Expression<Func<T, object>> exp)
{
if (exp.Body is MemberExpression)
{
var member = exp.Body as MemberExpression;
if (member.Expression is MemberExpression)
{
var parentMember = member.Expression as MemberExpression;
//parent member will be {p.Address}
//Now I'm trying to reconstruct an expression that I can combile
var parameterExpression = System.Linq.Expressions.Expression.Parameter(typeof(T), "p");
var lambdaExpression = System.Linq.Expressions.Expression.Lambda(parentMember, parameterExpression);
//Next Linethrows System.InvalidOperationException : Lambda Parameter not in scope
var found = lambdaExpression.Compile().DynamicInvoke(person);
return found;
}
}
return new object();
}
[测试]
public void TestExpression()
{
var person=newperson{Address={Street=“Bank Street”},Name=“Joe”};
表达式exp=p=>p.Address.Street;
Assert.AreEqual(“银行街”,exp.Compile().Invoke(person));
var owner=GetPropertyOwner(个人,经验);
Assert.AreEqual(所有者、个人、地址);
}
私有对象GetPropertyOwner(T根,表达式exp)
{
if(exp.Body是MemberExpression)
{
var member=将正文作为MemberExpression;
if(member.Expression是MemberExpression)
{
var parentMember=member.Expression作为MemberExpression;
//父成员将是{p.Address}
//现在我正试图重建一个我可以编译的表达式
var parameterExpression=System.Linq.Expressions.Expression.Parameter(typeof(T),“p”);
var lambdaExpression=System.Linq.Expressions.Expression.Lambda(parentMember,parameterExpression);
//下一行抛出System.InvalidOperationException:Lambda参数不在范围内
var found=lambdaExpression.Compile().DynamicInvoke(person);
发现退货;
}
}
返回新对象();
}
ParameterExpression对象是通过引用等式而不是名称进行比较的,因此lambdaExpression使用的“p”参数与parentMember中使用的参数不同。构建新lambda时,需要使用相同的ParameterExpression实例。尝试:
var parameterExpression = exp.Parameters[0];
令人惊叹的!我自己也发现了这一点,当时我正准备粘贴解决方案。很高兴知道如果我不这样做,我就不会被卡住了!谢谢