这篇文章主要介绍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; } } }
以上是“C#中如何实现代码解释器”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。