#c# #lambda #expression-trees
#c# #лямбда #деревья выражений
Вопрос:
Я пытаюсь разобраться в деревьях выражений и пришел к следующей проблеме, которую я не могу решить. Я пытаюсь сгенерировать простую лямбда-функцию, чтобы проверить, является ли целочисленное значение четным:
public static Func<int, bool> Generate_IsEven_Func()
{
var numParam = Expression.Parameter(typeof(int), "numParam");
var returnValue = Expression.Variable(typeof(bool), "returnValue");
var consoleWL = typeof(Console).GetMethod(nameof(Console.WriteLine), new[] { typeof(int) });
var body = Expression.Block(
// Scoping the variables
new[] { numParam, returnValue },
// Printing the current value for numParam
Expression.Call(
null,
consoleWL,
numParam
),
// Assign the default value to return
Expression.Assign(returnValue, Expression.Constant(false, typeof(bool))),
// If the numParam is even the returnValue becomes true
Expression.IfThen(
Expression.Equal(
Expression.Modulo(
numParam,
Expression.Constant(2, typeof(int))
),
Expression.Constant(0, typeof(int))
),
Expression.Assign(returnValue, Expression.Constant(true, typeof(bool)))
),
// value to return
returnValue
);
var lambda = Expression.Lambda<Func<int, bool>>(body, numParam).Compile();
return lambda;
}
Когда я вызываю вновь созданную лямбда-функцию, оказывается, что значение, которое я передаю в качестве аргумента, не «сопоставлено» с соответствующим параметром выражения — numParam
. Внутри блочного выражения я вызываю Console.WriteLine
метод для проверки текущего значения numParam
, и каждый раз оно равно 0:
var isEvenMethod = Generate_IsEven_Func();
var cond = isEvenMethod(21);
Console.WriteLine(cond);
// Prints:
// 0
// True
Ответ №1:
Вы не должны включать numParam
в массив переменных, которые вы передаете в качестве первого параметра Expression.Block(...)
— прямо сейчас вы, по сути, создаете новую numParam
переменную внутри блока, которая не связана с numParam
параметром, переданным лямбда. Поскольку переменная автоматически инициализируется значением по умолчанию int
(0), это объясняет вывод, который вы видите.
Комментарии:
1. Это сработало, большое спасибо! Эта область видимости все еще немного неясна для меня, когда дело доходит до деревьев выражений.