I'm trying to change a part of an expression tree, where a property X of type MyEnum is compared to some value x:
$model.X == .Constant<MyEnum>(x)
I want to modify the tree to substitute the comparison to compare a property Y of type Guid
with a value y (which will be derived from x).
$model.Y == .Constant<Guid>(y)
So I've inherited from ExpressionVisitor
and I've overridden VisitMember
to substitute Y for X, and I've overridden VisitConstant
to substitute y for x.
Running this yields the following InvalidOperationException
:
System.InvalidOperationException : Rewritten expression calls operator method 'Boolean op_Equality(System.Guid, System.Guid)', but the original node had no operator method. If this is is intentional, override 'VisitBinary' and change it to allow this rewrite.
My main question is: what do I have to do in VisitBinary
? And my side question is: why is the exception message telling that the original node had no operator method. I think this is not true. It didn't have op_Equality(System.Guid, System.Guid)
for sure but it had the equality operator for the MyEnum type, I assume.
I'm guessing from the name that MyEnum
is some sort of Enum
type.
Enum
types don't need operator methods, because CIL handles equality comparisons for them directly (the same is also true of the built-in integral, floating-point and boolean types).
There's no way to change the method through BinaryExression.Update()
(which will be called either explicitly in your visitor or implicitly because your visitor has changed one or both of the left and right expressions, and that's the default behaviour in that case) you will have to have VisitBinary()
create and return a new BinaryExpression
through the appropriate call to Expression.Equal()
.