利用C#动态编译功能实现像Javascript中的Eval的功能来将一段字符串进行数学运算

因为项目中有一个功能是由用户自己输入一个计算的表达式

如订单积分计算表达式:“{0} * 1.5 + 50”积分=订单金额 * 1.5倍 + 50积分

那么我的程序如何来计算出结果呢比如当前金额为100

那么表达式就为“100 * 1.5 +50”;

好以下测试代码

代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;
using System.Globalization;


namespace Z.Shop.Test.AutoCompiler
{
[NUnit.Framework.TestFixture]
public class Test1
{
[NUnit.Framework.TestFixtureSetUp]
public void SetUp()
{
log4net.Config.XmlConfigurator.Configure(
new System.IO.FileInfo("log4net.cfg.xml"));
}

public double Eval(string expression)
{
CSharpCodeProvider objCSharpCodePrivoder
= new CSharpCodeProvider();
ICodeCompiler objICodeCompiler
= objCSharpCodePrivoder.CreateCompiler();
CompilerParameters objCompilerParameters
= new CompilerParameters();
objCompilerParameters.ReferencedAssemblies.Add(
"System.dll");
objCompilerParameters.GenerateExecutable
= false;
objCompilerParameters.GenerateInMemory
= true;
//这里为生成的动态代码
StringBuilder sb = new StringBuilder();
sb.Append(
"using System;");
sb.Append(Environment.NewLine);
sb.Append(
"namespace DynamicCodeGenerate");
sb.Append(Environment.NewLine);
sb.Append(
"{");
sb.Append(Environment.NewLine);
sb.Append(
" public class DynamicCodeEval ");
sb.Append(Environment.NewLine);
sb.Append(
" {");
sb.Append(Environment.NewLine);
sb.Append(
" public object Eval()");
sb.Append(Environment.NewLine);
sb.Append(
" {");
sb.Append(Environment.NewLine);
sb.Append(
" return " + expression + ";"); //其实就是一个简单的表达式,如果要复杂的大家可以根据自己的情况改动
sb.Append(Environment.NewLine);
sb.Append(
" }");
sb.Append(Environment.NewLine);
sb.Append(
" }");
sb.Append(Environment.NewLine);
sb.Append(
"}");

string code = sb.ToString();

CompilerResults cr
= objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, code);
//这里是反射了
Assembly objAssembly = cr.CompiledAssembly;
object objDynamicCodeEval = objAssembly.CreateInstance("DynamicCodeGenerate.DynamicCodeEval");
MethodInfo objMI
= objDynamicCodeEval.GetType().GetMethod("Eval");
var result
= Convert.ToDouble(objMI.Invoke(objDynamicCodeEval, null));
return result;
}

[NUnit.Framework.Test]
public void T1()
{
var result
= Eval("100 * 1.5 +50");
Console.Write(result.ToString());
}
}
}

执行结果:200

Blog都是随笔,只当做笔记,不会有详细介绍,测试请慎重。。。
原文地址:https://www.cnblogs.com/JerryBaxia/p/1807579.html