5

My ultimate goal is to iterate through nested properties in a lambda expression and determine if any of the properties are null, but I am having trouble creating a new lambda expression based on a member expression.

Take this dummy method:

public static void DoStuff<TModelDetail, TValue>(Expression<Func<TModelDetail, TValue>> expr, TModelDetail detail)
{
    var memberExpression = expr.Body as MemberExpression;
    if (memberExpression == null && expr.Body is UnaryExpression)
    {
        memberExpression = ((UnaryExpression)expr.Body).Operand as MemberExpression;
    }

    var pe = Expression.Parameter(typeof(TModelDetail), "x");
    var convert = Expression.Convert(memberExpression, typeof(object));
    var wee = Expression.Lambda<Func<TModelDetail, object>>(convert, pe);
    var hey = wee.Compile()(detail);            
}

On the Compile.exec line I get the following error:

variable 'x' of type 'Blah' referenced from scope '', but it is not defined

where Blah is the type of TModelDetail.

How do I build the lambda with the MemberExpression? What I ultimately want to do is recursively find the root member expression, determine if it is null, and bubble up and determine if each subsequent member expression is null.

dtryan
  • 527
  • 3
  • 14
  • 2
    Do not create a new parameter, but use the one from `expr` because this one is used in your member expression. Currently, your `wee` is something like `x => y.Member` (where y is the parameter from `expr`) which doesn’t make sense. – ckuri Dec 15 '17 at 07:37
  • @ckuri Yep, that's it. Please put this as an answer so I can mark it as correct. – dtryan Dec 15 '17 at 07:51
  • 1
    Done, as per your suggestion. – ckuri Dec 15 '17 at 08:25
  • Have you seen that solution - https://stackoverflow.com/a/21936366/968003 ? – Alex Klaus Jan 02 '18 at 10:43

1 Answers1

4

expr already contains a parameter (let's call it y) which is bound by your member expression, so expr looks like y => y.Member.Something.

When your construct the new lambda Expression wee you are giving it a new parameter x, so wee looks like x => y.Member, which doesn’t make sense.

Therefore you need to reuse the parameter from expr for wee.

ckuri
  • 3,784
  • 2
  • 15
  • 17