星期三 十二月 16, 2009 23:28
cSharp动态调用和反射的一个绝佳例子
之前看反射那一章,真把个人看郁闷了。不巧的是,看到很多业内人士的专业博客说,不会这个也搞了几年的项目开发。哎。顿时打消了学习这个知识的念头。不过,挺巧的是,今天又遇到了一个讲这个内容的章节,只不过内容更具体了。
这样一个动态调用的程序,貌似实现了一个编译器的功能。在Textbox里写上代码,能在程序下方看到编译结果。有趣的是,当代码出错的时候,能在程序中看到错误信息:
//核心代码
public string ComplieAndRun(string input,out bool hasError)
{
CompilerResults cResults = null;
string returnData = null;
hasError = false;
using(Microsoft.CSharp.CSharpCodeProvider provider =new CSharpCodeProvider())
{
StringBuilder sb = new StringBuilder();
sb.Append(prefix);
sb.Append(input);
sb.Append(postfix);
CompilerParameters option = new CompilerParameters();
option.GenerateInMemory = true;
cResults=provider.CompileAssemblyFromSource(option, sb.ToString());
}
if (cResults.Errors.HasErrors)
{
hasError = true;
StringBuilder errMessage = new StringBuilder();
foreach (CompilerError err in cResults.Errors)
{
errMessage.AppendFormat("{0}:{1}", err.Line, err.ErrorText);
}
returnData = errMessage.ToString();
}
else
{
TextWriter temp=Console.Out;
StringWriter sw = new StringWriter();
Console.SetOut(sw);
Type myType = cResults.CompiledAssembly.GetType("myDriver");
myType.InvokeMember("Run", BindingFlags.InvokeMethod|BindingFlags.Public | BindingFlags.Static, null, null, null);
Console.SetOut(temp);
returnData = sw.ToString();
}
return returnData;
}
}
//每次动态调用后,通过应用程序域卸载掉
public class DynamicRunAppInDomain
{
public string CompileAndRun(string input,out bool hasErr)
{
AppDomain app = AppDomain.CreateDomain("DynamicRun");
DynamicRun dr = (DynamicRun)app.CreateInstanceAndUnwrap("ShaoMingboDrive", "WpfApplication1.DynamicRun");
string res = dr.ComplieAndRun(input,out hasErr);
AppDomain.Unload(app);
return res;
}
}
这里是一个该程序的二进制文件:动态调用demo (55).net framework 3.5 required
如果您的机器上没有安装.net,不妨下载这个打包好的文件:动态调用Setup (56)
- Category: code, csharp-note
- No Comments
