• 转:将字符串或表达式直接转为C#可执行代码的办法


    原文地址:http://blog.csdn.net/qwlovedzm/article/details/6292147

    近日有个项目有不少的计算公式,而且要求能定制,如何能将字符串或表达式直接转为C#的可执行代码就好了。

    经过从网上查阅资料,发现有一个开源的工具类,将它修改后改为如下效果:

    1. using System; 
    2. using System.Data; 
    3. using System.Configuration; 
    4. using System.Text; 
    5. using System.CodeDom.Compiler; 
    6. using Microsoft.CSharp; 
    7. using System.Reflection; 
    8.  
    9. namespace SSEC.Math 
    10.     /// <summary>    
    11.     /// 本类用来将字符串转为可执行文本并执行    
    12.     /// </summary>    
    13.     publicclass MyEvaluator 
    14.     { 
    15.         #region 构造函数 
    16.  
    17.         /// <summary>    
    18.         /// 可执行串的构造函数    
    19.         /// </summary>    
    20.         /// <param name="items">    
    21.         /// 可执行字符串数组    
    22.         /// </param>    
    23.         public MyEvaluator(EvaluatorItem[] items) 
    24.         { 
    25.             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析    
    26.         } 
    27.  
    28.         /// <summary>    
    29.         /// 可执行串的构造函数    
    30.         /// </summary>    
    31.         /// <param name="returnType">返回值类型</param>    
    32.         /// <param name="expression">执行表达式</param>    
    33.         /// <param name="name">执行字符串名称</param>    
    34.         public MyEvaluator(Type returnType, string expression, string name) 
    35.         { 
    36.             //创建可执行字符串数组    
    37.             EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) }; 
    38.             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析    
    39.         } 
    40.  
    41.         /// <summary>    
    42.         /// 可执行串的构造函数    
    43.         /// </summary>    
    44.         /// <param name="item">可执行字符串项</param>    
    45.         public MyEvaluator(EvaluatorItem item) 
    46.         { 
    47.             EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组    
    48.             ConstructEvaluator(items);      //调用解析字符串构造函数进行解析    
    49.         } 
    50.  
    51.         /// <summary>    
    52.         /// 解析字符串构造函数    
    53.         /// </summary>    
    54.         /// <param name="items">待解析字符串数组</param>    
    55.         privatevoid ConstructEvaluator(EvaluatorItem[] items) 
    56.         { 
    57.             //创建C#编译器实例 
    58.             CodeDomProvider provider = CodeDomProvider.CreateProvider("C#"); 
    59.              
    60.             //过时了 
    61.             //ICodeCompiler comp = provider.CreateCompiler(); 
    62.              
    63.             //编译器的传入参数    
    64.             CompilerParameters cp = new CompilerParameters(); 
    65.             cp.ReferencedAssemblies.Add("system.dll");              //添加程序集 system.dll 的引用    
    66.             cp.ReferencedAssemblies.Add("system.data.dll");         //添加程序集 system.data.dll 的引用    
    67.             cp.ReferencedAssemblies.Add("system.xml.dll");          //添加程序集 system.xml.dll 的引用    
    68.             cp.GenerateExecutable = false;                          //不生成可执行文件    
    69.             cp.GenerateInMemory = true;                             //在内存中运行    
    70.  
    71.             StringBuilder code = new StringBuilder();               //创建代码串    
    72.             /* 
    73.              *  添加常见且必须的引用字符串 
    74.              */ 
    75.             code.Append("using System; /n"); 
    76.             code.Append("using System.Data; /n"); 
    77.             code.Append("using System.Data.SqlClient; /n"); 
    78.             code.Append("using System.Data.OleDb; /n"); 
    79.             code.Append("using System.Xml; /n"); 
    80.  
    81.             code.Append("namespace SSEC.Math { /n");                  //生成代码的命名空间为EvalGuy,和本代码一样    
    82.  
    83.             code.Append("  public class _Evaluator { /n");          //产生 _Evaluator 类,所有可执行代码均在此类中运行    
    84.             foreach (EvaluatorItem item in items)               //遍历每一个可执行字符串项    
    85.             { 
    86.                 code.AppendFormat("    public {0} {1}() ",          //添加定义公共函数代码    
    87.                                   item.ReturnType.Name,             //函数返回值为可执行字符串项中定义的返回值类型    
    88.                                   item.Name);                       //函数名称为可执行字符串项中定义的执行字符串名称    
    89.                 code.Append("{ ");                                  //添加函数开始括号    
    90.                 code.AppendFormat("return ({0});", item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值    
    91.                 code.Append("}/n");                                 //添加函数结束括号    
    92.             } 
    93.             code.Append("} }");                                 //添加类结束和命名空间结束括号    
    94.  
    95.             //得到编译器实例的返回结果    
    96.             CompilerResults cr = provider.CompileAssemblyFromSource(cp, code.ToString());//comp 
    97.  
    98.             if (cr.Errors.HasErrors)                            //如果有错误    
    99.             { 
    100.                 StringBuilder error = new StringBuilder();          //创建错误信息字符串    
    101.                 error.Append("编译有错误的表达式: ");                //添加错误文本    
    102.                 foreach (CompilerError err in cr.Errors)            //遍历每一个出现的编译错误    
    103.                 { 
    104.                     error.AppendFormat("{0}/n", err.ErrorText);     //添加进错误文本,每个错误后换行    
    105.                 } 
    106.                 thrownew Exception("编译错误: " + error.ToString());//抛出异常    
    107.             } 
    108.             Assembly a = cr.CompiledAssembly;                       //获取编译器实例的程序集    
    109.             _Compiled = a.CreateInstance("SSEC.Math._Evaluator");     //通过程序集查找并声明 SSEC.Math._Evaluator 的实例    
    110.         } 
    111.         #endregion 
    112.         #region 公有成员 
    113.         /// <summary>    
    114.         /// 执行字符串并返回整型值    
    115.         /// </summary>    
    116.         /// <param name="name">执行字符串名称</param>    
    117.         /// <returns>执行结果</returns>    
    118.         publicint EvaluateInt(string name) 
    119.         { 
    120.             return (int)Evaluate(name); 
    121.         } 
    122.         /// <summary>    
    123.         /// 执行字符串并返回双精度值    
    124.         /// </summary>    
    125.         /// <param name="name">执行字符串名称</param>    
    126.         /// <returns>执行结果</returns>    
    127.         publicdouble EvaluateDouble(string name) 
    128.         { 
    129.             return (double)Evaluate(name); 
    130.         } 
    131.         /// <summary>    
    132.         /// 执行字符串并返回长整型数值    
    133.         /// </summary>    
    134.         /// <param name="name">执行字符串名称</param>    
    135.         /// <returns>执行结果</returns>    
    136.         publiclong EvaluateLong(string name) 
    137.         { 
    138.             return (long)Evaluate(name); 
    139.         } 
    140.         /// <summary>    
    141.         /// 执行字符串并返回十进制数值    
    142.         /// </summary>    
    143.         /// <param name="name">执行字符串名称</param>    
    144.         /// <returns>执行结果</returns>    
    145.         publicdecimal EvaluateDecimal(string name) 
    146.         { 
    147.             return (decimal)Evaluate(name); 
    148.         } 
    149.         /// <summary>    
    150.         /// 执行字符串并返回字符串型值    
    151.         /// </summary>    
    152.         /// <param name="name">执行字符串名称</param>    
    153.         /// <returns>执行结果</returns>    
    154.         publicstring EvaluateString(string name) 
    155.         { 
    156.             return (string)Evaluate(name); 
    157.         } 
    158.         /// <summary>    
    159.         /// 执行字符串并返回布尔型值    
    160.         /// </summary>    
    161.         /// <param name="name">执行字符串名称</param>    
    162.         /// <returns>执行结果</returns>    
    163.         publicbool EvaluateBool(string name) 
    164.         { 
    165.             return (bool)Evaluate(name); 
    166.         } 
    167.         /// <summary>    
    168.         /// 执行字符串并返 object 型值    
    169.         /// </summary>    
    170.         /// <param name="name">执行字符串名称</param>    
    171.         /// <returns>执行结果</returns>    
    172.         publicobject Evaluate(string name) 
    173.         { 
    174.             MethodInfo mi = _Compiled.GetType().GetMethod(name);//获取 _Compiled 所属类型中名称为 name 的方法的引用    
    175.             return mi.Invoke(_Compiled, null);                  //执行 mi 所引用的方法    
    176.         } 
    177.         #endregion 
    178.         #region 静态成员 
    179.         /// <summary>    
    180.         /// 执行表达式并返回整型值    
    181.         /// </summary>    
    182.         /// <param name="code">要执行的表达式</param>    
    183.         /// <returns>运算结果</returns>    
    184.         staticpublicint EvaluateToInteger(string code) 
    185.         { 
    186.             MyEvaluator eval = new MyEvaluator(typeof(int), code, staticMethodName);//生成 Evaluator 类的对像    
    187.             return (int)eval.Evaluate(staticMethodName);                        //执行并返回整型数据    
    188.         } 
    189.         /// <summary>    
    190.         /// 执行表达式并返回双精度值    
    191.         /// </summary>    
    192.         /// <param name="name">执行字符串名称</param>    
    193.         /// <returns>执行结果</returns>    
    194.         staticpublicdouble EvaluateToDouble(string code) 
    195.         { 
    196.             MyEvaluator eval = new MyEvaluator(typeof(double), code, staticMethodName);//生成 Evaluator 类的对像    
    197.             return (double)eval.Evaluate(staticMethodName);  
    198.         } 
    199.         /// <summary>    
    200.         /// 执行表达式并返回长整型数值    
    201.         /// </summary>    
    202.         /// <param name="name">执行字符串名称</param>    
    203.         /// <returns>执行结果</returns>    
    204.         staticpubliclong EvaluateToLong(string code) 
    205.         { 
    206.             MyEvaluator eval = new MyEvaluator(typeof(long), code, staticMethodName);//生成 Evaluator 类的对像    
    207.             return (long)eval.Evaluate(staticMethodName);  
    208.         } 
    209.         /// <summary>    
    210.         /// 执行表达式并返回十进制数值    
    211.         /// </summary>    
    212.         /// <param name="name">执行字符串名称</param>    
    213.         /// <returns>执行结果</returns>    
    214.         staticpublicdecimal EvaluateToDecimal(string code) 
    215.         { 
    216.             MyEvaluator eval = new MyEvaluator(typeof(decimal), code, staticMethodName);//生成 Evaluator 类的对像    
    217.             return (decimal)eval.Evaluate(staticMethodName);  
    218.         } 
    219.         /// <summary>    
    220.         /// 执行表达式并返回字符串型值    
    221.         /// </summary>    
    222.         /// <param name="code">要执行的表达式</param>    
    223.         /// <returns>运算结果</returns>    
    224.         staticpublicstring EvaluateToString(string code) 
    225.         { 
    226.             MyEvaluator eval = new MyEvaluator(typeof(string), code, staticMethodName);//生成 Evaluator 类的对像    
    227.             return (string)eval.Evaluate(staticMethodName);                     //执行并返回字符串型数据    
    228.         } 
    229.         /// <summary>    
    230.         /// 执行表达式并返回布尔型值    
    231.         /// </summary>    
    232.         /// <param name="code">要执行的表达式</param>    
    233.         /// <returns>运算结果</returns>    
    234.         staticpublicbool EvaluateToBool(string code) 
    235.         { 
    236.             MyEvaluator eval = new MyEvaluator(typeof(bool), code, staticMethodName);//生成 Evaluator 类的对像    
    237.             return (bool)eval.Evaluate(staticMethodName);                       //执行并返回布尔型数据    
    238.         } 
    239.         /// <summary>    
    240.         /// 执行表达式并返回 object 型值    
    241.         /// </summary>    
    242.         /// <param name="code">要执行的表达式</param>    
    243.         /// <returns>运算结果</returns>    
    244.         staticpublicobject EvaluateToObject(string code) 
    245.         { 
    246.             MyEvaluator eval = new MyEvaluator(typeof(object), code, staticMethodName);//生成 Evaluator 类的对像    
    247.             return eval.Evaluate(staticMethodName);                             //执行并返回 object 型数据    
    248.         } 
    249.         #endregion 
    250.         #region 私有成员 
    251.         /// <summary>    
    252.         /// 静态方法的执行字符串名称    
    253.         /// </summary>    
    254.         privateconststring staticMethodName = "__foo"
    255.         /// <summary>    
    256.         /// 用于动态引用生成的类,执行其内部包含的可执行字符串    
    257.         /// </summary>    
    258.         object _Compiled = null
    259.         #endregion 
    260.     } 
    261.  
    262.  
    263.     /// <summary>    
    264.     /// 可执行字符串项(即一条可执行字符串)    
    265.     /// </summary>    
    266.     publicclass EvaluatorItem 
    267.     { 
    268.         /// <summary>    
    269.         /// 返回值类型    
    270.         /// </summary>    
    271.         public Type ReturnType; 
    272.         /// <summary>    
    273.         /// 执行表达式    
    274.         /// </summary>    
    275.         publicstring Expression; 
    276.         /// <summary>    
    277.         /// 执行字符串名称    
    278.         /// </summary>    
    279.         publicstring Name; 
    280.         /// <summary>    
    281.         /// 可执行字符串项构造函数    
    282.         /// </summary>    
    283.         /// <param name="returnType">返回值类型</param>    
    284.         /// <param name="expression">执行表达式</param>    
    285.         /// <param name="name">执行字符串名称</param>    
    286.         public EvaluatorItem(Type returnType, string expression, string name) 
    287.         { 
    288.             ReturnType = returnType; 
    289.             Expression = expression; 
    290.             Name = name; 
    291.         } 
    292.     } 

    下面是测试类:

    1. class Test 
    2.     { 
    3.         /// <summary> 
    4.         /// The main entry point for the application. 
    5.         /// </summary> 
    6.         [STAThread] 
    7.         staticvoid Main(string[] args) 
    8.         { 
    9.             Console.WriteLine("Test0: {0}", MyEvaluator.EvaluateToInteger("(30 + 4) * 2")); 
    10.             Console.WriteLine("Test1: {0}", MyEvaluator.EvaluateToString("/"Hello /" + /"There/"")); 
    11.             Console.WriteLine("Test2: {0}", MyEvaluator.EvaluateToBool("30 == 40")); 
    12.             Console.WriteLine("Test3: {0}", MyEvaluator.EvaluateToObject("new DataSet()")); 
    13.             Console.WriteLine("Test4: {0}", MyEvaluator.EvaluateToDouble("(12.4+2.2)*0.4")); 
    14.             Console.WriteLine("Test5: {0}", MyEvaluator.EvaluateToLong("(12+1000)*1000")); 
    15.             Console.WriteLine("Test6: {0}", MyEvaluator.EvaluateToString("/"double max==/"+double.MaxValue"));//decimal.MaxValue+/",/"+ 
    16.              
    17.  
    18.             EvaluatorItem[] items = { 
    19.                                     new EvaluatorItem(typeof(int), "(30 + 4) * 2", "GetNumber"), 
    20.                                     new EvaluatorItem(typeof(string), "/"Hello /" + /"There/"", "GetString"), 
    21.                                     new EvaluatorItem(typeof(bool), "30 == 40", "GetBool"), 
    22.                                     new EvaluatorItem(typeof(object), "new DataSet()", "GetDataSet"
    23.                                     }; 
    24.  
    25.             MyEvaluator eval = new MyEvaluator(items); 
    26.             Console.WriteLine("TestStatic0: {0}", eval.EvaluateInt("GetNumber")); 
    27.             Console.WriteLine("TestStatic1: {0}", eval.EvaluateString("GetString")); 
    28.             Console.WriteLine("TestStatic2: {0}", eval.EvaluateBool("GetBool")); 
    29.             Console.WriteLine("TestStatic3: {0}", eval.Evaluate("GetDataSet")); 
    30.             Console.ReadLine(); 
    31.         } 
    32.     } 

    经测试,想要的结果终于出来了。

  • 相关阅读:
    属性选择器
    Map
    tomcat 启动失败
    find for /f 分割字符串 bat
    oracle 1day
    scott lock
    oracle oracle sqldeveloper 12505 创建连接失败
    oracle sql developer 启动java.exe设置错误
    servlet post response.sendRedirect 乱码

  • 原文地址:https://www.cnblogs.com/wadeheng/p/3047558.html
Copyright © 2020-2023  润新知