简单的C#代码解释器

开发 后端
本文介绍简单的C#代码解释器,我们可以在控制台中输入一行 C#代码,然后程序自动编译并执行这一行代码,将结果显示给我们。

1、C#代码解释器简介

能够动态执行 C#代码是一件很酷的功能,比如,我们可以在控制台中输入一行 C#代码,然后程序自动编译并执行这一行代码,将结果显示给我们。这差不多就是一个最简单的 C#代码解释器了。

动态执行 C#代码又是一件很有用的功能,比如,我们可以将某些代码写在某个文件之中,由程序集在执行时进行加载,改变这些代码不用中止程序,当程序再次加载这些代码时,就自动执行的是新代码了。

2、简单的 C#代码解释器

usingSystem;  
usingSystem.Collections.Generic;  
usingSystem.Reflection;  
usingSystem.Globalization;  
usingMicrosoft.CSharp;  
usingSystem.CodeDom;  
usingSystem.CodeDom.Compiler;  
usingSystem.Text;  
usingSystem.IO;  
usingSystem.Xml;  
 
namespaceTest  
{  
classProgram  
{  
staticvoidMain(string[]args)  
{  
Console.Write(">>");  
Stringcmd;  
Contextcxt=newContext();  
while((cmd=Console.ReadLine().Trim())!="exit")  
{  
if(!String.IsNullOrEmpty(cmd))  
{  
Console.WriteLine();  
cxt.Invoke(cmd);  
}  
Console.Write("\n>>");  
}  
}  
}  
 
publicclassContext  
{  
publicCSharpCodeProviderCodeProvider{get;set;}  
publicIDictionary<String,Assembly>Assemblys{get;set;}  
 
publicContext()  
{  
CodeProvider=newCSharpCodeProvider(newDictionary<string,string>()
{{"CompilerVersion","v3.5"}});  
Assemblys=newDictionary<String,Assembly>();   Assembly[]al=AppDomain.CurrentDomain.GetAssemblies();   foreach(Assemblyainal)   {   AddAssembly(a);   }   AppDomain.CurrentDomain.AssemblyLoad+=newAssemblyLoadEventHandler
(CurrentDomain_AssemblyLoad);  
}     privatevoidAddAssembly(Assemblya)   {   if(a!=null)   {   Assemblys.Add(a.FullName,a);   }   }     voidCurrentDomain_AssemblyLoad(objectsender,AssemblyLoadEventArgsargs)   {   Assemblya=args.LoadedAssembly;   if(!Assemblys.ContainsKey(a.FullName))   {   AddAssembly(a);   }   }     publicCompilerParametersCreateCompilerParameters()   {   CompilerParameterscp=newCompilerParameters();   cp.GenerateExecutable=false;   cp.GenerateInMemory=true;   if(Assemblys!=null)   {   foreach(AssemblyainAssemblys.Values)   {   cp.ReferencedAssemblies.Add(a.Location);   }   }   returncp;   }     publicvoidInvoke(Stringcmd)   {   StringinputCmdString=cmd.Trim();   if(String.IsNullOrEmpty(inputCmdString))return;     StringfullCmd=BuildFullCmd(inputCmdString);     CompilerResultscr=CodeProvider.CompileAssemblyFromSource
(CreateCompilerParameters(),fullCmd);  
  if(cr.Errors.HasErrors)   {   BooleanrecompileSwitch=true;     foreach(CompilerErrorerrincr.Errors)   {   //CS0201:Onlyassignment,call,increment,decrement,andnewobjectexpressionscanbe   //usedasastatement   if(!err.ErrorNumber.Equals("CS0201"))   {   recompileSwitch=false;   break;   }   }     //重新编译   if(recompileSwitch)   {   StringdynaName="TempArg_Dynamic_"+DateTime.Now.Ticks.ToString();   inputCmdString=String.Format("var{0}=",dynaName)+inputCmdString;   inputCmdString+=";\nSystem.Console.WriteLine("+dynaName+");";     fullCmd=BuildFullCmd(inputCmdString);   cr=CodeProvider.CompileAssemblyFromSource(CreateCompilerParameters(),fullCmd);   }     if(cr.Errors.HasErrors)   {   Console.WriteLine("编译错误:");   foreach(CompilerErrorerrincr.Errors)   {   Console.WriteLine(err.ErrorNumber);   Console.WriteLine(err.ErrorText);   }     return;   }   }     Assemblyassem=cr.CompiledAssembly;   ObjectdynamicObject=assem.CreateInstance("Test.DynamicClass");   Typet=assem.GetType("Test.DynamicClass");   MethodInfominfo=t.GetMethod("MethodInstance");   minfo.Invoke(dynamicObject,null);   }     privateStringBuildFullCmd(StringinputCmdString)   {   StringStringfullCmd=String.Empty;     fullCmd+=@"   namespaceTest   {   publicclassDynamicClass   {   publicvoidMethodInstance()   {   "+inputCmdString+@";   }   }   }";   returnfullCmd;   }   }  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.

【编辑推荐】

  1. 分析C#不安全代码
  2. 浅析C#调用ImageAnimator
  3. C#连接Access、SQL Server数据库
  4. 浅谈C#固定的和活动的变量
  5. 介绍C#中的值类型
责任编辑:佚名 来源: 博客园
相关推荐

2009-08-13 17:36:54

编译C#代码

2009-08-31 17:53:20

C#实现索引器

2009-08-06 15:12:22

C#异常机制

2009-09-01 10:35:19

C# 3.0编译器

2009-08-31 14:54:35

C#对象浏览器

2013-06-05 10:11:20

索引器C#

2009-08-31 18:32:01

C# ListBoxE

2009-09-17 16:53:15

C#数组

2009-08-26 14:31:08

C#打印文件

2009-08-21 17:11:05

C#摄像头

2009-09-07 15:27:04

C# MessageB

2009-08-13 10:15:50

C#读取Excel

2009-08-19 10:09:21

C#和C++

2009-08-19 15:38:59

C#代码

2009-08-07 17:12:07

C# DLL函数

2009-08-27 15:34:38

C#命名空间

2009-08-21 17:31:58

C#垃圾回收

2009-08-06 18:15:13

C# SQL Serv

2009-08-20 16:25:59

C# 匿名方法

2009-09-16 09:01:40

C#多维数组
点赞
收藏

51CTO技术栈公众号