Недопонимание скомпилированных деревьев выражений? - PullRequest
8 голосов
/ 26 февраля 2012

У меня есть это выражение:

Expression<Func<string, bool>> f = s => s.Length < 5;

enter image description here

ParameterExpression p = Expression.Parameter (typeof (string), "s");
MemberExpression stringLength = Expression.Property (p, "Length");
ConstantExpression five = Expression.Constant (5);
BinaryExpression comparison = Expression.LessThan (stringLength, five);
Expression<Func<string, bool>> lambda= Expression.Lambda<Func<string, bool>> (comparison, p);

// позволяет: test

Func<string, bool> runnable = lambda.Compile();
Console.WriteLine (runnable ("kangaroo")); // False
Console.WriteLine (runnable ("dog")); //True

Я хочу спросить о1011 *

Что он компилирует?И в чем разница между первым выполнением и последующим выполнением ...?

Компиляция должна происходить один раз, а потом не повторяться ....

Что / Как это помогаетя?

Ответы [ 3 ]

10 голосов
/ 26 февраля 2012

Когда вы строите дерево выражений во время выполнения, код не генерируется. Это способ представления кода .NET во время выполнения.

Как только вы вызываете метод .Compile в дереве выражений, выдается фактический код IL для преобразования этого дерева выражений в делегата (Func<string, bool> в вашем случае), который вы можете вызвать во время выполнения. Поэтому код, который представляет это дерево выражений, может быть выполнен только после его компиляции.

Вызов Compile - дорогостоящая операция. По сути, вы должны вызывать его один раз, а затем кэшировать полученный делегат, который вы могли бы использовать для многократного вызова кода.

2 голосов
/ 26 февраля 2012

Compile() берет дерево выражений (которое представляет собой представление данных некоторой логики) и преобразует его в IL, который затем может быть выполнен непосредственно в качестве делегата.

Единственное отличиемежду первым выполнением и последующим выполнением существует вероятность того, что Compile() не вызовет JIT-компиляцию из IL в собственный код процессора.Это может произойти при первом исполнении.

2 голосов
/ 26 февраля 2012

Expression<Func<string,bool>> является только представлением выражения, оно не может быть выполнено .Вызов Compile() дает вам скомпилированный делегат, фрагмент кода, который вы можете вызвать.По сути, ваша программа составляет небольшой фрагмент кода во время выполнения, а затем вызывает его, как если бы он был обработан компилятором.Это то, что делают последние две строки вашего кода: как вы можете видеть, скомпилированный фрагмент может анализировать длину строки, которую вы передаете, - когда длина меньше пяти, вы получаете True назад;когда их пять или более, вы получаете False.

То, что происходит при первом выполнении скомпилированного фрагмента, зависит от платформы и не должно быть обнаружено программистами, использующими платформу .NET.

...