0

I have a problem evaluation conditional lambdaexpressions, using System.Linq.Expressions. Here the full example Code:

using System;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressionTree
{
    class Program<TType>
    {
        public TType Data { get; set; }

        public void RegisterLambda<TProp>(Expression<Func<TType, TProp>> expression)
        {
            if (expression.Body.NodeType == ExpressionType.Conditional)
            {
                ConditionalExpression condExp = (ConditionalExpression)expression.Body;
                var condTest = condExp.Test;
                var paramExpression = Expression.Parameter(typeof(TType), "x");
                var lambda = Expression.Lambda(condTest, paramExpression);
                var deleg = lambda.Compile();   // this will raise an InvalidOperationException: variable 'x' of type 'ExpressionTree.DataObject'
                                                // referenced from scope '', but it is not defined
                var testResult = deleg.DynamicInvoke(Data);
            }
            if (expression.Body.NodeType == ExpressionType.MemberAccess)
            {
                var pi = expression.GetPropertyInfo();
                Console.WriteLine(pi.GetValue(Data));
            }
            if (expression.Body.NodeType == ExpressionType.Constant)
            {
                ConstantExpression ce = (ConstantExpression)expression.Body;
                Console.WriteLine(ce.Value);
            }
        }
    }

    class Start
    {
        static void Main(string[] args)
        {
            Program<DataObject> P = new Program<DataObject>();
            P.Data = new DataObject();
            P.Data.DisplayName = "1234567890";
            P.RegisterLambda(x => x.DisplayName);
            P.RegisterLambda(x => x.DisplayName.Length <= 3 ? "Foobar" : x.DisplayName);
            P.RegisterLambda<string>(something => "abc");
        }
    }
    class DataObject
    {
        public string DisplayName { get; set; }
    }

    static class Extensions
    {
        public static PropertyInfo GetPropertyInfo(this LambdaExpression expression)
        {
            if (expression.Body is UnaryExpression unaryExp)
            {
                if (unaryExp.Operand is MemberExpression memberExp)
                {
                    return (PropertyInfo)memberExp.Member;
                }
            }
            else if (expression.Body is MemberExpression memberExp)
            {
                return (PropertyInfo)memberExp.Member;
            }
            throw new Exception();
        }
    }
}

While calling the 2nd RegisterLambda, which is a ternery conditional lambda. The execution fails on the Compile()-line. Does anyone have a clue to solve that problem? I have tried many combinations using ParameterExpression Thanks in advance!

André D.
  • 1
  • 3
  • Pass the original parameter expression to the new lambda instead of creating a new one: `var lambda = Expression.Lambda(condTest, expression.Parameters[0]);` – Mathias R. Jessen Nov 16 '21 at 13:13
  • Does this answer your question? [variable '' of type '' referenced from scope '', but it is not defined](https://stackoverflow.com/questions/30556911/variable-of-type-referenced-from-scope-but-it-is-not-defined) – Mathias R. Jessen Nov 16 '21 at 13:14

0 Answers0