Получение дерева выражений из скриптового языка в c #

2

Я ищу способ генерировать дерево выражений из сценария на С#. В настоящее время я использую IronPython, но я открыт для переключения, если бы было проще получить дерево выражений. Кроме того, я понимаю, что могу получить это от реализации своего собственного языка сценариев; однако, я бы предпочел использовать тот, который уже создан, если это возможно.

Если рекомендуется использовать язык сценариев помимо IronPython, он должен иметь: операторы if (предпочтительно с и/или), математические операции (+, -, *,/, log,%, ^), циклы и возможность добавления пользовательские функции.

В качестве примера того, что я пытаюсь сделать, я включил два блока кода. Один рассчитывает бонус, используя дерево выражений, которое создается и затем компилируется:

using System;
using System.Linq.Expressions;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee() { Salary = 100000, BonusPct = .05 };
            Expression<Func<Employee, double>> calcbonusExp = x => x.Salary * x.BonusPct; ;
            var calcBonus = calcbonusExp.Compile();
            Console.WriteLine(calcBonus(employee));
            Console.WriteLine(calcbonusExp.NodeType);
            Console.WriteLine(calcbonusExp.Body);
            Console.WriteLine(calcbonusExp.Body.NodeType);
            foreach (var param in calcbonusExp.Parameters)
            {
                Console.WriteLine(param.Name);
            }
            Console.Read();
        }
}

public class Employee
    {
        public double Salary { get; set; }
        public double BonusPct { get; set; }
    }
}

Другой рассчитывает бонус, используя IronPython:

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using System;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee() { Salary = 100000, BonusPct = .05 };

            ScriptEngine engine = Python.CreateEngine();
            ScriptScope scope = engine.CreateScope();

            ScriptSource source = engine.Execute(
                @"def calcBonus(employee):
                      return employee.Salary * employee.BonusPct 
                ", scope);
            var calcAdd = scope.GetVariable("calcBonus");
            var result = calcAdd(employee);
            Console.WriteLine(result);
            Console.Read();
        }
    }

    public class Employee
    {
        public double Salary { get; set; }
        public double BonusPct { get; set; }
    }
}

Есть ли способ получить такое же дерево выражений из блока кода, используя IronPython (или любой другой язык сценариев)?

  • 1
    Второй пример не создает дерево выражений как таковое. Это создает делегата. Общим здесь является то, что вы создаете делегата и вызываете его. Это то, что вы действительно после? Потому что есть API-интерфейс сценариев, который может эффективно это сделать. Деревья выражений больше относятся к представлению кода как данных, которые можно проверять и анализировать, но это не то, что делает второй пример.
Теги:
ironpython
expression-trees

1 ответ

2
Лучший ответ

Вы можете использовать Roslyn для создания объекта Expression из скрипта, написанного на С# или VB.

См. Например, https://www.strathweb.com/2018/01/easy-way-to-create-ac-lambda-expression-from-a-string-with-roslyn/

Ещё вопросы

Сообщество Overcoder
Наверх
Меню