C#中如何实现代码解释器

发布时间:2021-12-01 11:45:05 作者:小新
阅读:310
开发者专用服务器限时活动,0元免费领! 查看>>

这篇文章主要介绍C#中如何实现代码解释器,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

1、C#代码解释器简介

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

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

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

  1. usingSystem;  

  2. usingSystem.Collections.Generic;  

  3. usingSystem.Reflection;  

  4. usingSystem.Globalization;  

  5. usingMicrosoft.CSharp;  

  6. usingSystem.CodeDom;  

  7. usingSystem.CodeDom.Compiler;  

  8. usingSystem.Text;  

  9. usingSystem.IO;  

  10. usingSystem.Xml;  

  11. namespaceTest  

  12. {  

  13. classProgram  

  14. {  

  15. staticvoidMain(string[]args)  

  16. {  

  17. Console.Write(">>");  

  18. Stringcmd;  

  19. Contextcxt=newContext();  

  20. while((cmd=Console.ReadLine().Trim())!="exit")  

  21. {  

  22. if(!String.IsNullOrEmpty(cmd))  

  23. {  

  24. Console.WriteLine();  

  25. cxt.Invoke(cmd);  

  26. }  

  27. Console.Write("\n>>");  

  28. }  

  29. }  

  30. }  

  31. publicclassContext  

  32. {  

  33. publicCSharpCodeProviderCodeProvider{get;set;}  

  34. publicIDictionary<String,Assembly>Assemblys{get;set;}  

  35. publicContext()  

  36. {  

  37. CodeProvider=newCSharpCodeProvider(newDictionary<string,string>()
    {{"CompilerVersion","v3.5"}});  

  38. Assemblys=newDictionary<String,Assembly>();  

  39. Assembly[]al=AppDomain.CurrentDomain.GetAssemblies();  

  40. foreach(Assemblyainal)  

  41. {  

  42. AddAssembly(a);  

  43. }  

  44. AppDomain.CurrentDomain.AssemblyLoad+=newAssemblyLoadEventHandler
    (CurrentDomain_AssemblyLoad);  

  45. }  

  46. privatevoidAddAssembly(Assemblya)  

  47. {  

  48. if(a!=null)  

  49. {  

  50. Assemblys.Add(a.FullName,a);  

  51. }  

  52. }  

  53. voidCurrentDomain_AssemblyLoad(objectsender,AssemblyLoadEventArgsargs)  

  54. {  

  55. Assemblya=args.LoadedAssembly;  

  56. if(!Assemblys.ContainsKey(a.FullName))  

  57. {  

  58. AddAssembly(a);  

  59. }  

  60. }  

  61. publicCompilerParametersCreateCompilerParameters()  

  62. {  

  63. CompilerParameterscp=newCompilerParameters();  

  64. cp.GenerateExecutable=false;  

  65. cp.GenerateInMemory=true;  

  66. if(Assemblys!=null)  

  67. {  

  68. foreach(AssemblyainAssemblys.Values)  

  69. {  

  70. cp.ReferencedAssemblies.Add(a.Location);  

  71. }  

  72. }  

  73. returncp;  

  74. }  

  75. publicvoidInvoke(Stringcmd)  

  76. {  

  77. StringinputCmdString=cmd.Trim();  

  78. if(String.IsNullOrEmpty(inputCmdString))return;  

  79. StringfullCmd=BuildFullCmd(inputCmdString);  

  80. CompilerResultscr=CodeProvider.CompileAssemblyFromSource
    (CreateCompilerParameters(),fullCmd);  

  81. if(cr.Errors.HasErrors)  

  82. {  

  83. BooleanrecompileSwitch=true;  

  84. foreach(CompilerErrorerrincr.Errors)  

  85. {  

  86. //CS0201:Onlyassignment,call,increment,decrement,andnewobjectexpressionscanbe  

  87. //usedasastatement  

  88. if(!err.ErrorNumber.Equals("CS0201"))  

  89. {  

  90. recompileSwitch=false;  

  91. break;  

  92. }  

  93. }  

  94. //重新编译  

  95. if(recompileSwitch)  

  96. {  

  97. StringdynaName="TempArg_Dynamic_"+DateTime.Now.Ticks.ToString();  

  98. inputCmdString=String.Format("var{0}=",dynaName)+inputCmdString;  

  99. inputCmdString+=";\nSystem.Console.WriteLine("+dynaName+");";  

  100. fullCmd=BuildFullCmd(inputCmdString);  

  101. cr=CodeProvider.CompileAssemblyFromSource(CreateCompilerParameters(),fullCmd);  

  102. }  

  103. if(cr.Errors.HasErrors)  

  104. {  

  105. Console.WriteLine("编译错误:");  

  106. foreach(CompilerErrorerrincr.Errors)  

  107. {  

  108. Console.WriteLine(err.ErrorNumber);  

  109. Console.WriteLine(err.ErrorText);  

  110. }  

  111. return;  

  112. }  

  113. }  

  114. Assemblyassem=cr.CompiledAssembly;  

  115. ObjectdynamicObject=assem.CreateInstance("Test.DynamicClass");  

  116. Typet=assem.GetType("Test.DynamicClass");  

  117. MethodInfominfo=t.GetMethod("MethodInstance");  

  118. minfo.Invoke(dynamicObject,null);  

  119. }  

  120. privateStringBuildFullCmd(StringinputCmdString)  

  121. {  

  122. StringStringfullCmd=String.Empty;  

  123. fullCmd+=@"  

  124. namespaceTest  

  125. {  

  126. publicclassDynamicClass  

  127. {  

  128. publicvoidMethodInstance()  

  129. {  

  130. "+inputCmdString+@";  

  131. }  

  132. }  

  133. }";  

  134. returnfullCmd;  

  135. }  

  136. }  

以上是“C#中如何实现代码解释器”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

推荐阅读:
  1. Hello world代码解释
  2. C#名词解释

开发者交流群:

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

上一篇:C#抽象类怎么理解

下一篇:C#代码格式化百分比数据怎么实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》
开发者交流群×