zoukankan      html  css  js  c++  java
  • 如何将一段文本编译成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

  • 相关阅读:
    EasyUI 取得选中行数据
    为什么给的待遇很丰厚,我的90后员工还是要走?
    ***ECharts图表入门和最佳实践
    ***百度统计图表Echarts的php实现类,支持柱形图、线形图、饼形图
    <?php $sql = <<<EOF 。。。。EOF;?>这种写法是什么意思
    ***mysql中查询今天、昨天、上个月sql语句
    ***iOS开发中@selector的理解与应用
    ***Xcode Interface Builder或Storyboard中可建立那两种连接?
    什么是Nib文件?(Nib文件是一种特殊类型的资源文件,它用于保存iPhone OS或Mac OS X应用程序的用户接口)
    IOS笔记 #pragma mark的用法和作用(方便查找和导航代码)
  • 原文地址:https://www.cnblogs.com/x-poior/p/7550675.html
Copyright © 2011-2022 走看看