从C#中的脚本语言获取表达式树

时间:2018-11-10 23:28:18

标签: c# ironpython expression-trees

我正在寻找一种从C#脚本生成表达式树的方法。当前,我正在使用IronPython,但是如果可以更轻松地获取表达式树,我可以进行切换。另外,我意识到我可以通过实现自己的脚本语言来实现。但是,如果可能的话,我宁愿使用已经创建的。

如果建议使用IronPython以外的脚本语言,则需要具备以下条件:if语句(最好使用and / or),数学运算(+,-,*,/,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 个答案:

答案 0 :(得分:2)

您可以使用Roslyn从用C#或VB编写的脚本中创建一个Expression对象。

例如参见https://www.strathweb.com/2018/01/easy-way-to-create-a-c-lambda-expression-from-a-string-with-roslyn/