Comments 2
Спасибо автору за статью! Действительно полезная информация касательно деревьев выражений, собранная в одном месте.
0
Я на визиторы смотрю как на ужас. Наверное наша ORM давно бы погрязла в куче кассов и непонятных иерархий.
Простая, постоянно требующя решения задача подмены параметра в теле лямбды превращается в армагеддон. Да она решается созданием одного ReplacingExpressionVisitor (такой себе класик)
И такого вызова:
А еще она решаться может и вот так:
Вроде одинаково, но гипотетически усложним задачу, мало того, что надо подменить параметр, так и прибавить единички ко всем целочисленным константам. Тут уже надо городить новые классы или даже пропускать через несколько визиторов, а мы в лямбде для Transform просто усложняем условие. Это может быть ощутимо заметно на гигантском дереве, такие иногда получаются когда запрос к базе содержит монструидальный Where, созданный динамичиски какой-то UI библиотекой.
Минус Transform в том что если вы придумываете кастомные Expression, тут уже сильно не потрансформируешь, или придется расширять метод.
Если интересна реализация, ее можно найти в библиотеке CodeJam или в нашей ORM linq2db.
В защиту данного подхода скажу так, за 5 лет мне ни разу не пришлось писать новый Visitor.
Простая, постоянно требующя решения задача подмены параметра в теле лямбды превращается в армагеддон. Да она решается созданием одного ReplacingExpressionVisitor (такой себе класик)
И такого вызова:
var newParam = Expression.Parameter(someType);
var newBody = ReplacingExpressionVisitor.Replace(lambda.Paramters[0], newParam, lambda.Body);
А еще она решаться может и вот так:
var newParam = Expression.Parameter(someType);
var newBody = lambda.Body.Transform(e => e == lambda.Paramters[0] ? newParam : e);
Вроде одинаково, но гипотетически усложним задачу, мало того, что надо подменить параметр, так и прибавить единички ко всем целочисленным константам. Тут уже надо городить новые классы или даже пропускать через несколько визиторов, а мы в лямбде для Transform просто усложняем условие. Это может быть ощутимо заметно на гигантском дереве, такие иногда получаются когда запрос к базе содержит монструидальный Where, созданный динамичиски какой-то UI библиотекой.
Минус Transform в том что если вы придумываете кастомные Expression, тут уже сильно не потрансформируешь, или придется расширять метод.
Если интересна реализация, ее можно найти в библиотеке CodeJam или в нашей ORM linq2db.
В защиту данного подхода скажу так, за 5 лет мне ни разу не пришлось писать новый Visitor.
+2
Sign up to leave a comment.
Деревья выражений в C# на примере нахождения производной (Expression Tree Visitor vs Pattern matching)