C#字符串表达式的动态编译及执行

C#是一个静态语言,也就是需要将源代码编译到二进制文件以后才能被执行,不像Python,Matlab等是动态执行的,也就是通过输入语句就可以被解析器解析执行。
那C#有没有办法实现“字符串代码”的执行呢?办法是有的,.Net Framework支持在程序运行过程中将字符串编译到程序集(dll或者exe),并可以加载。
主要用到的命名空间包含:

using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;

具体的类的使用可以参考MSDN;下面是自己的测试代码,备忘。

 1 static void Main(string[] args)
 2         {
 3             //类名
 4             string className = "TestClass";
 5             //方法名
 6             string MethodName = "TestMethod";
 7             //函数体
 8             string expressionText = "return Math.Pow(x,2);";
 9             //C#代码字符串
10             string txt = string.Format(@"using System;sealed class {0}{{public double {1} (double x){{{2}}}}}",className,MethodName,expressionText);
11             //构造一个CSharp代码生成器
12             CSharpCodeProvider provider = new CSharpCodeProvider();
13             //构造一个编译器参数设置
14             CompilerParameters para = new CompilerParameters();
15 
16             /*
17              //para可以需要按照实际要求进行设置,比如添加程序集引用,如下
18                para.ReferencedAssemblies.Add("System.dll");
19              */
20 
21             //编译到程序集,有重载,也可以从文件加载,传入参数为文件路径字符串数组
22             var rst = provider.CompileAssemblyFromSource(para, new string[] { txt });
23 
24             //判断是否有编译错误
25             if(rst.Errors.Count>0)
26             {
27                 foreach(CompilerError item in rst.Errors)
28                 {
29                     Console.WriteLine(item.Line+":"+item.ErrorText);
30                 }
31                 return;
32             }
33 
34             //获取程序集
35             var assemble = rst.CompiledAssembly;
36 
37             //通过反射获取类类型
38             Type t=assemble.GetType(className);
39 
40             //通过类型构造实例
41             var instance=Activator.CreateInstance(t);
42 
43             //通过反射获取类型方法
44             MethodInfo method = t.GetMethod(MethodName);
45 
46             //调用实例上的方法
47             var val = method.Invoke(instance, new object[] { 4 });
48 
49             Console.WriteLine(val);
50             Console.ReadKey();
51         }

 

上一篇:非等占空比信号的产生方法


下一篇:【LeetCode刷题记录】3. 无重复字符的最长子串