您好,登錄后才能下訂單哦!
這篇文章主要介紹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#代碼解釋器
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("編譯錯(cuò)誤:");
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#中如何實(shí)現(xiàn)代碼解釋器”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(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)容。