Я пытаюсь изменить часть дерева выражений, где свойство X типа MyEnum сравнивается с некоторым значением х:переписано выражение вызывает метод оператора ... но исходный узел не имеет метода оператора
$model.X == .Constant<MyEnum>(x)
Я хочу изменить дерево, чтобы заменить сравнение, чтобы сравнить свойство Y типа Guid
со значением y (которое будет получено из x).
$model.Y == .Constant<Guid>(y)
Так что я унаследовал от ExpressionVisitor
и я переопределен VisitMember
заменить Y на X, и я переопределен VisitConstant
заменить у на х.
Запуск этого приводит к следующим InvalidOperationException
:
System.InvalidOperationException: Переписанное выражение вызывает метод оператора Логическое op_Equality (System.Guid, System.Guid) ', но исходный узел не имел какой-либо метода оператора. Если это намеренно, переопределите «VisitBinary» и измените его, чтобы разрешить эту перезапись.
Мой главный вопрос: что мне делать в VisitBinary
? И мой вопрос: почему сообщение об исключении говорит о том, что исходный узел не имеет метода оператора. Я думаю, что это неправда. У него не было op_Equality(System.Guid, System.Guid)
, но у него был оператор равенства для типа MyEnum.
Переопределение VisitBinary - лучший выбор в любом случае, потому что он ставит всю логику в одном месте. Интересно, как должен выглядеть код OPs перед тем, как это сделать, вероятно, запутанным с состоянием экземпляра, которое осуществляется через вызовы VisitC. В VisitBinary он может просто осмотреть двух детей, и если они совпадают, выполните переписывание. +1 – usr
Это очень интересное понимание. Я не знал, что классы Expression уже включают знания «CIL» еще до их компиляции. – Dejan
Его более фабричный метод, который делает это, чем сам экземпляр. Стоит отметить, что если бы вы начали с двоичного выражения с другим операционным методом, обновление все равно потерпело бы неудачу, но с другим исключением, поэтому деталь реализации влияет на характер исключения (что, возможно, еще не идеально), но не так ли. –