【转】netcore 下的 C# 表达式求值
转自:
需求场景: 表达式为系统功能维护,提取后,将可执行的表达式放入Net Core 下if(表达式)来判定是否正确,因维护的表达式为字符串类型, 例如 "2>1" 需要实现 if(2>1) { //表达式正确逻辑 } else { //表达式不成立逻辑 } netframework 下的 codedom 代码已经不能用了,会报错,改用Roslyn来写: 先安装包 核心代码,尝试了好久 可以快乐的测试了 install-package Microsoft.CodeAnalysis.CSharp
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
public class CsEvaluator
{
/// <summary>CSharp 表达式求值</summary>
/// <param name="expression">CSharp 表达式。如:2.5, DateTime.Now</param>
public object Eval(string expression)
{
// 代码
var text = string.Format(@"
using System;
public class Calculator
{{
public static object Evaluate() {{ return {0}; }}
}}", expression);
// 编译生成程序集
var tree = SyntaxFactory.ParseSyntaxTree(text);
var compilation = CSharpCompilation.Create(
"calc.dll",
new[] { tree },
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
references: new[] {
MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
});
Assembly compiledAssembly;
using (var stream = new MemoryStream())
{
var compileResult = compilation.Emit(stream);
compiledAssembly = Assembly.Load(stream.GetBuffer());
}
// 用反射执行方法
var calculatorClass = compiledAssembly.GetType("Calculator");
var evaluateMethod = calculatorClass.GetMethod("Evaluate");
return evaluateMethod.Invoke(null, null);
}
}
var eval = new CsEvaluator();
var b = eval.Eval("5 > 4");
var d = eval.Eval("2.5");
var dt1 = eval.Eval("new DateTime(2018,1,1)");
var dt2 = eval.Eval("DateTime.Now");