Peter
Peter

Reputation: 1

Issue with C# lambda return System.Linq.Expressions.Expression

I have a big problem with assigning the following code and I don't know how to solve it and I want to use lambda operators.

 System.Linq.Expressions.Expression expression = null;
 if (typeof(ICustomTypeDescriptor).IsAssignableFrom(sourceType))
 {
            System.Linq.Expressions.Expression expression2 = System.Linq.Expressions.Expression.Convert(parameterExpression, typeof(ICustomTypeDescriptor));
            expression = (ICustomTypeDescriptor t, object o) =>
            {
                t.GetProperties()[propertyName].GetValue(o)
                }
            ;
            return System.Linq.Expressions.Expression.Invoke(expression, new System.Linq.Expressions.Expression[]
            {
                expression2,
                parameterExpression
            });
        }

The problem is in this part enter image description here

Can it be declared in any other way ?

ERROR

Unable to convert lambda expression element to "Expression" type because it is not a delegate type

Upvotes: 0

Views: 168

Answers (3)

Peter
Peter

Reputation: 1

Thanks guys, I'm sorry for not writing for so long, I found a solution and changed the code a bit, I tried with every proposal but unfortunately it threw the same error. Maybe my solution for someone will be helpful in the future :)

  private static LambdaExpression GetLambdaWithPropertyNullCheck(
      IEnumerable source,
      string propertyName,
      ParameterExpression parameterExpression,
      Type sourceType)
    {
        string[] strArray = propertyName.Split('.');
        LambdaExpression lambdaExpression;
        if (strArray.GetLength(0) > 1)
        {
            System.Linq.Expressions.Expression expression1 = parameterExpression.GetValueExpression(propertyName, sourceType);
            if (expression1.Type != typeof(object))
                expression1 = (System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.Convert(expression1, typeof(object));
            System.Linq.Expressions.Expression expression2 = (System.Linq.Expressions.Expression)null;
            string propertyName1 = string.Empty;
            int length = strArray.GetLength(0);
            for (int index = 0; index < length; ++index)
            {
                if (index == 0)
                {
                    expression2 = (System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.Equal(parameterExpression.GetValueExpression(strArray[index], sourceType), (System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.Constant((object)null));
                    propertyName1 = strArray[index];
                }
                else if (index < length - 1)
                {
                    propertyName1 = propertyName1 + (object)'.' + strArray[index];
                    expression2 = (System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.OrElse(expression2, (System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.Equal(parameterExpression.GetValueExpression(propertyName1, sourceType), (System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.Constant((object)null)));
                }
            }
            lambdaExpression = System.Linq.Expressions.Expression.Lambda((System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.Condition(expression2, (System.Linq.Expressions.Expression)System.Linq.Expressions.Expression.Constant((object)null), expression1, typeof(object)), parameterExpression);
        }
        else
            lambdaExpression = System.Linq.Expressions.Expression.Lambda(parameterExpression.GetValueExpression(propertyName, sourceType), parameterExpression);
        return lambdaExpression;
    }

Upvotes: 0

ravichandra vydhya
ravichandra vydhya

Reputation: 969

Instead of this line,

System.Linq.Expressions.Expression expression = null;

Create a delegate and assign a variable to your expression.

delegate    System.Linq.Expressions.Expression Myexpression(ICustomTypeDescriptor t, object o);

Myexpression expression = (ICustomTypeDescriptor t, object o) => t.GetProperties()[propertyName].GetValue(o);

Upvotes: 1

Kirjava
Kirjava

Reputation: 232

You are using multilines lambda expression, which is ok. But you need to end each line with ";".

I think this would work but without the whole code it will be hard to be sure :

System.Linq.Expressions.Expression expression = null;
if (typeof(ICustomTypeDescriptor).IsAssignableFrom(sourceType))
{
    System.Linq.Expressions.Expression expression2 = System.Linq.Expressions.Expression.Convert(parameterExpression, typeof(ICustomTypeDescriptor));
    expression = (ICustomTypeDescriptor t, object o) =>
    {
        t.GetProperties()[propertyName].GetValue(o);
    };
    return System.Linq.Expressions.Expression.Invoke(expression, new System.Linq.Expressions.Expression[]
    {
        expression2,
        parameterExpression
    });
}

You can also go for singleline lambda :

System.Linq.Expressions.Expression expression = null;
if (typeof(ICustomTypeDescriptor).IsAssignableFrom(sourceType))
{
    System.Linq.Expressions.Expression expression2 = System.Linq.Expressions.Expression.Convert(parameterExpression, typeof(ICustomTypeDescriptor));
    expression = (ICustomTypeDescriptor t, object o) => t.GetProperties()[propertyName].GetValue(o);
    return System.Linq.Expressions.Expression.Invoke(expression, new System.Linq.Expressions.Expression[]
    {
        expression2,
        parameterExpression
    });
}

Please care, I haven't tested the code to check if I'm not wrong.

Upvotes: 1

Related Questions