Просто добавлю немного правильного ответа Марка:
Являются ли деревья выражений LINQ ориентированными графами без циклов?
Прежде всего, да, дерево выражений - это DAG - ориентированный ациклический граф.
Мы знаем, что они являются ациклическими, потому что деревья выражений неизменны , и поэтому должны быть построены из листьев. В такой ситуации невозможно создать цикл, потому что все узлы в цикле должны быть выделены last , и, очевидно, этого не произойдет.
Поскольку части являются неизменяемыми, выражение «дерево» не обязательно должно быть деревом как таковым. Как указывает Марк, необходимо повторно использовать ссылку для параметра; так мы определяем, когда используется объявленный параметр. Несколько странно, хотя и законно, повторно использовать и другие части. Например, если вы хотите представить дерево выражений для тела (int x)=>(x + 1) * (x + 1)
, вы можете создать дерево выражений для (x + 1)
, а затем создать узел умножения, в котором оба потомка были этим деревом выражений.
При использовании ExpressionVisitor для посещения LambdaExpression, ParameterExpression посещается дважды. Есть ли способ использовать ExpressionVisitor для посещения LambdaExpression, чтобы все узлы посещались ровно один раз и в определенном, хорошо известном порядке (предварительный заказ, заказ, пост-заказ и т. Д.)?
ExpressionVisitor - абстрактный класс. Вы можете сделать свою собственную конкретную версию, имеющую семантику, которая вам нравится. Например, вы можете переопределить метод Visit так, чтобы он поддерживал HashSet уже увиденных узлов и не вызывал Accept на узлах, которые он ранее принял.