怎样将一段文本编译成C#内存程序的进度

string code = null;

// 1. 生成要编译的代码。(示例为了简单直接从程序集内的资源中读取)
Stream stram = typeof(CodeDOM).Assembly
            .GetManifestResourceStream("TestOptimizeReflection.用户手册.txt");
using( StreamReader sr = new StreamReader(stram) ) {
    code = sr.ReadToEnd();
}

//Console.WriteLine(code);

// 2. 设置编译参数,主要是指定将要引用哪些程序集
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("OptimizeReflection.dll");

// 3. 获取编译器并编译代码
// 由于我的代码使用了【自动属性】特性,所以需要 C# .3.5版本的编译器。
// 获取与CLR匹配版本的C#编译器可以这样写:CodeDomProvider.CreateProvider("CSharp")

Dictionary<string, string> dict = new Dictionary<string, string>();
dict["CompilerVersion"] = "v3.5";
dict["WarnAsError"] = "false";

CSharpCodeProvider csProvider = new CSharpCodeProvider(dict);
CompilerResults cr = csProvider.CompileAssemblyFromSource(cp, code);

// 4. 检查有没有编译错误
if( cr.Errors != null && cr.Errors.HasErrors ) {
    foreach( CompilerError error in cr.Errors )
        Console.WriteLine(error.ErrorText);

    return;
}

// 5. 获取编译结果,它是编译后的程序集
Assembly asm = cr.CompiledAssembly;

全体进度分成5个步骤,它们已用注释标识出来了,那里不再重复了。

回去顶部

哪些调用编译结果

前面的代码把一段文本字符串编译成了程序集,以往还有最终一个难题:如何调用编译结果?

答案:有三种办法,

  1. 直接调用方法。
  2. 实例化程序集中的档次,以接口情势调用方法。
    实际那三种情势都亟待使用反射,用反射定位到要调用的门类和办法。

先是种方法须要在转移代码时,生成的类名和方式名是肯定的,在调用方法时,大家有二个挑选:

  1. 用反射的办法调用(那里只是两次反射)。
    2.
    为格局生成委托(用上篇博客介绍的措施),然后依据委托调用。

其次种办法需求在变化代码时,首先要定义一个接口,保障生成的代码能促成指定的接口,
唯独用反射找到要调用的档次名称,用反射大概委托调用构造方法创设项目实例,最后依据接口去调用。
大家熟习的ASPX页面就是拔取了那种艺术来落实的。

那三种格局也得以这么区分:

  1. 如果生成的法门是静态方法,应该接纳第一种形式。
  2. 一旦生成的不二法门是实例方法,那么选取第两种格局是客观的。

对于目前的演示,我利用了第一种方法了,因为类名和章程名称都以优先确定的还要落实起来相比较简单。

// 6. 找到目标方法,并调用
Type t = asm.GetType("OptimizeReflection.用户手册");
MethodInfo method = t.GetMethod("Main");
method.Invoke(null, null);

 参考:http://www.cnblogs.com/fish-li/archive/2013/02/24/2924673.html\#\_labelStart

相关文章