Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq Expressions: The binary operator Equal is not defined for the types 'MyEnum' and 'System.Enum'

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)

enter image description here

PS.

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!?

like image 525
serhio Avatar asked Nov 12 '22 06:11

serhio


1 Answers

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.

like image 98
Samuel Neff Avatar answered Nov 14 '22 22:11

Samuel Neff