Использование лямбды внутри Linq.Выражения

#c# #linq #methodinfo

Вопрос:

Мне нужно вызвать лямбду из Linq.Выражение. Я знаю, что могу получить некоторую информацию о методе из лямбды, как это:

 Func<double, double> square = x => x * x;
MethodInfo mInfo = square.Method;
 

Но для этого MethodInfo требуется System.RuntimeServices.Closure первый аргумент. Поскольку я использую .NET Core, этот класс является внутренним для System.Linq.Expressions . Даже когда экземпляр этого класса создается с помощью отражения, я не могу вызвать square из System.Linq.Выражение.

Есть ли какое-либо обходное решение для этого? Я пишу простой вычислитель формул, но мне нужны лямбды для реализации таких мыслей, как логика предикатов, Ньютон-Рафсон и т. Д.

Обновленный:

Этот код не работает:

         static void Main(string[] args) =>
            Console.WriteLine(DoubleIt()(4));

        static double CallAndDouble(Func<double, double> f, double x)
        {
            return f(x)   f(x);
        }

        static Func<double, double> DoubleIt()
        {
            var input = Expression.Parameter(typeof(double), "x");
            var call = Expression.Call(typeof(Program).GetMethod(nameof(CallAndDouble)),
                CreateLambda(), input);
            return Expression.Lambda<Func<double, double>>(call, input).Compile();
        }

        static Expression CreateLambda()
        {
            var input = Expression.Parameter(typeof(double), "x");
            var mult = Expression.Multiply(input, input);
            return Expression.Lambda<Func<double, double>>(mult, input);
        }
 

В реальном коде у меня будут некоторые библиотечные функции, принимающие лямбды в качестве аргументов (например CallAndDouble , из приведенного выше кода).

Комментарии:

1. Изменено var на Func<double, double> .

2. Единственное, что вы можете сделать, это построить выражение, которое вызывает эту square лямбду (т. Е. Expression<Func<double, double>> expr = x => square(x) ). Невозможно построить выражение, представляющее операцию x * x

3. Даже с учетом изменений трудно точно знать, чего вы пытаетесь достичь. Пожалуйста, предоставьте больше контекста, включая то, как вы планируете использовать дерево выражений позже.

4. Добавлено больше кода.

5. Ваш код работает для меня: dotnetfiddle.net/oEGtpG . Это происходит (4 * 4) (4 * 4) потому, что это то, что ты построил, но эй. Что именно в этом не так?

Ответ №1:

Решена @canton7. Просто опечатка: мне не хватало биндингфлагов.