溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C#中如何實(shí)現(xiàn)代碼解釋器

發(fā)布時(shí)間:2021-12-01 11:45:05 來(lái)源:億速云 閱讀:293 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹C#中如何實(shí)現(xiàn)代碼解釋器,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

1、C#代碼解釋器簡(jiǎn)介

能夠動(dòng)態(tài)執(zhí)行 C#代碼是一件很酷的功能,比如,我們可以在控制臺(tái)中輸入一行 C#代碼,然后程序自動(dòng)編譯并執(zhí)行這一行代碼,將結(jié)果顯示給我們。這差不多就是一個(gè)最簡(jiǎn)單的 C#代碼解釋器了。

動(dòng)態(tài)執(zhí)行 C#代碼又是一件很有用的功能,比如,我們可以將某些代碼寫(xiě)在某個(gè)文件之中,由程序集在執(zhí)行時(shí)進(jìn)行加載,改變這些代碼不用中止程序,當(dāng)程序再次加載這些代碼時(shí),就自動(dòng)執(zhí)行的是新代碼了。

2、簡(jiǎn)單的 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.  

  12. namespaceTest  

  13. {  

  14. classProgram  

  15. {  

  16. staticvoidMain(string[]args)  

  17. {  

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

  19. Stringcmd;  

  20. Contextcxt=newContext();  

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

  22. {  

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

  24. {  

  25. Console.WriteLine();  

  26. cxt.Invoke(cmd);  

  27. }  

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

  29. }  

  30. }  

  31. }  

  32.  

  33. publicclassContext  

  34. {  

  35. publicCSharpCodeProviderCodeProvider{get;set;}  

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

  37.  

  38. publicContext()  

  39. {  

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

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

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

  43. foreach(Assemblyainal)  

  44. {  

  45. AddAssembly(a);  

  46. }  

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

  48. }  

  49.  

  50. privatevoidAddAssembly(Assemblya)  

  51. {  

  52. if(a!=null)  

  53. {  

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

  55. }  

  56. }  

  57.  

  58. voidCurrentDomain_AssemblyLoad(objectsender,AssemblyLoadEventArgsargs)  

  59. {  

  60. Assemblya=args.LoadedAssembly;  

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

  62. {  

  63. AddAssembly(a);  

  64. }  

  65. }  

  66.  

  67. publicCompilerParametersCreateCompilerParameters()  

  68. {  

  69. CompilerParameterscp=newCompilerParameters();  

  70. cp.GenerateExecutable=false;  

  71. cp.GenerateInMemory=true;  

  72. if(Assemblys!=null)  

  73. {  

  74. foreach(AssemblyainAssemblys.Values)  

  75. {  

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

  77. }  

  78. }  

  79. returncp;  

  80. }  

  81.  

  82. publicvoidInvoke(Stringcmd)  

  83. {  

  84. StringinputCmdString=cmd.Trim();  

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

  86.  

  87. StringfullCmd=BuildFullCmd(inputCmdString);  

  88.  

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

  90.  

  91. if(cr.Errors.HasErrors)  

  92. {  

  93. BooleanrecompileSwitch=true;  

  94.  

  95. foreach(CompilerErrorerrincr.Errors)  

  96. {  

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

  98. //usedasastatement  

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

  100. {  

  101. recompileSwitch=false;  

  102. break;  

  103. }  

  104. }  

  105.  

  106. //重新編譯  

  107. if(recompileSwitch)  

  108. {  

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

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

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

  112.  

  113. fullCmd=BuildFullCmd(inputCmdString);  

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

  115. }  

  116.  

  117. if(cr.Errors.HasErrors)  

  118. {  

  119. Console.WriteLine("編譯錯(cuò)誤:");  

  120. foreach(CompilerErrorerrincr.Errors)  

  121. {  

  122. Console.WriteLine(err.ErrorNumber);  

  123. Console.WriteLine(err.ErrorText);  

  124. }  

  125.  

  126. return;  

  127. }  

  128. }  

  129.  

  130. Assemblyassem=cr.CompiledAssembly;  

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

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

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

  134. minfo.Invoke(dynamicObject,null);  

  135. }  

  136.  

  137. privateStringBuildFullCmd(StringinputCmdString)  

  138. {  

  139. StringStringfullCmd=String.Empty;  

  140.  

  141. fullCmd+=@"  

  142. namespaceTest  

  143. {  

  144. publicclassDynamicClass  

  145. {  

  146. publicvoidMethodInstance()  

  147. {  

  148. "+inputCmdString+@";  

  149. }  

  150. }  

  151. }";  

  152. returnfullCmd;  

  153. }  

  154. }  

以上是“C#中如何實(shí)現(xiàn)代碼解釋器”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI