I have built an expression tree which seems to result in an expression of type Expression<Func<object, bool>>
and a return type bool
which I think is what I want. But when I try to compile it into a Func<object, bool>
I am getting the following System.ArgumentException
:
"Expression of type 'System.Func`2[System.Object,System.Boolean]' cannot be used for return type 'System.Boolean"
My end goal is to create a return a function I can use on different objects where I know the property name and test if the property satisfies a certain condition. I don't understand why the final step is failing because from the exception it seems like I do have the anticipated Expression<Func<object, bool>>
and I would think it can be used with return type bool
. Here is the code:
public delegate Expression ComparisonExpressionDelegate(Expression property, Expression value);
public class ConditionCompiler
{
public class TestClass
{
public string StringProperty1 { get; set; }
public string StringProperty2 { get; set; }
public string StringProperty3 { get; set; }
public int IntProperty1 { get; set; }
public double DoubleProperty1 { get; set; }
}
public static Func<object, bool> Test() //This is called
{
PropertyInfo property = typeof(TestClass).GetProperty(nameof(TestClass.StringProperty1));
object value = "1";
return CompileExpression(property, value);
}
public static Func<object, bool> CompileExpression(PropertyInfo property, object value)
{
ParameterExpression obj = Expression.Parameter(typeof(object), "obj");
Expression resultExpression = CreateExpression(property, value);
Func<object, bool> resultLambda
= Expression.Lambda<Func<object, bool>>(resultExpression, obj).Compile(); //Issue is here
return resultLambda;
}
public static Expression CreateExpression(PropertyInfo property, object value)
{
ParameterExpression obj = Expression.Parameter(typeof(object), "obj");
bool isGetMethodStatic = property.GetGetMethod().IsStatic;
UnaryExpression typedTarget = Expression.Convert(obj, property.DeclaringType);
MemberExpression memberAccess = Expression.Property(isGetMethodStatic ? null : typedTarget, property);
UnaryExpression boxedGetter = Expression.TypeAs(memberAccess, typeof(object));
ConstantExpression valueExpression = Expression.Constant(value);
ComparisonExpressionDelegate comparisonExpressionDelegate = ToString_Equals_ToString_Expression;
Expression conditionExpression = comparisonExpressionDelegate(boxedGetter, valueExpression);
LambdaExpression conditionExpressionLambda = Expression.Lambda(conditionExpression, obj);
return conditionExpressionLambda;
}
private static ComparisonExpressionDelegate ToString_Equals_ToString_Expression
= (property, value) => Expression.Equal(
Expression.Call(
typeof(string),
nameof(String.Compare),
null,
Expression.Call(property, "ToString", null),
value, Expression.Constant(StringComparison.OrdinalIgnoreCase)
),
Expression.Constant(0)
);
}
Aucun commentaire:
Enregistrer un commentaire