views:

31

answers:

1

Hi,

Given an expression that points to a property in an object graph, I want to retrieve the instance that owns the property withing that graph. I've been struggling. The current code just gives me System.InvalidOperationException : Lambda Parameter not in scope

    [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();
    }
A: 

ParameterExpression objects are compared by reference equality, not by name, so the "p" parameter that lambdaExpression takes is not the same as the one used in parentMember. You will need to use the same ParameterExpression instance when you build a new lambda. Try:

var parameterExpression = exp.Parameters[0];
Quartermeister
Awesome! I was just about the paste the solution as I found that out myself. Great to know I would have not been stuck if I didn't! Thanks
Max