I convert some of data from a WinGrid to an expression, in order to filter some output to the user. I have an initial collection (of MyObjectType), I apply some dynamic filters, and I obtain a filtered collection.
I have problems however with an enumeration - property of MyObjectType.
the enumeration is a standard enumeration
Public Enum MyEnum
A
B
C
End Enum
this is how I obtain the expression:
Dim constantExpression As ConstantExpression
If TypeOf Value Is [Enum] Then
constantExpression = Expression.Constant(Value, GetType([Enum]))
Else
constantExpression = Expression.Constant(Value, Value.GetType())
End If
...
Dim expr As Expression = Nothing
Dim objectPropertyParam = Expression.Property(objectParam, objectPropertyName)
Select Case Me.Operation
Case ComparisonOperator.Contains, ComparisonOperator.NotContains
...
Case ComparisonOperator.NotEqual
...
Case ComparisonOperator.Equal
' THE EXCEPTION IS HERE ---------------------------------------
expr = Expression.Equal(objectPropertyParam, constantExpression)
Case ComparisonOperator.GreatherThanOrEqual
expr = Expression.GreaterThanOrEqual(objectPropertyParam, constantExpression)
Case ComparisonOperator.LessThanOrEqual
expr = Expression.LessThanOrEqual(objectPropertyParam, constantExpression)
End Select
then the following exception occurs:
The binary operator Equal is not defined for the types 'MyEnum' and 'System.Enum'.
at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull) at System.Linq.Expressions.Expression.Equal(Expression left, Expression right)
I observed that if I do
expr = Expression.Equal(objectPropertyParam,
Expression.Convert(constantExpression, GetType(MyEnum)))
This Works, but I'd would like do not specity each type of enumerations like this, because is a generic function!?
The problem you're running into is the difference between Object.Equals
and MyEnum.Equals
. Instead of using Expression.Equal
use Expression.Call
to call the constant's Equals
method.
Alternatively, if this is always done with enums then you can convert them all to integers safely (or whatever the largest backing type is). Then you don't have to hard-code converting to a specific enum--it will work with any integer-based enum. If it's used for things besides enums, then using Expression.Call
is best.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With