• 使用CompilerResults 方法动态的编译类


    -------------------今天愚人节,祝ITer 愚人节快乐----------------------

    好吧,我out了,我是第一次使用这个类。觉得比较新奇,所以就整出来,大家共享贡献。

    需要实现这个demo,你需要导入以下三个命名空间:

    using System.Reflection;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;

    第一部分:CompileClass

    在这个方法中,我们放了自己hard code 在运行需要动态编译的类的方法体,当然在现实项目中,我们可以传自己需要处理的类即可。我在这个类里面创建了一string类型的name和一个int类型的age。

    代码如下:

    public Assembly CompileClass()
    {
        string code = @"
             public class Test
             {
                public string name{get; set;} 
                
                public int age{get; set;}
    
             }";
    
        CompilerResults compilerResults = CompileScript(code);//调用CompileScript 方法。
    
        if (compilerResults.Errors.HasErrors)
        {
            throw new InvalidOperationException("Expression has a syntax error.");
        }
    
        Assembly assembly = compilerResults.CompiledAssembly;//得到程序集对象。里面包含了类、接口、方法、属性。。。等等。
    
        return assembly;
    }

    对上面的代码没有多少难度,需要注意的是,我们写些了一个方法-----CompilerScript,主要是根据传进来的类 字符串,生成CompilerResult为返回类型的结果。

    第二部分:CompilerScript

    代码如下:

    public  CompilerResults CompileScript(string source)
    {
        CompilerParameters parms = new CompilerParameters();
    
        parms.GenerateExecutable = false;// 是否生成exe 可执行文件。
        parms.GenerateInMemory = true;//是否在内存中生成space
        parms.IncludeDebugInformation = false;//是否包含debug 信息
    
        CodeDomProvider compiler = CSharpCodeProvider.CreateProvider("CSharp");
    
        return compiler.CompileAssemblyFromSource(parms, source);
    }

    对CodeDomProvider 类而言,它是一个有关动态编译的类。可以查看博客园的专题报告CodeDom 。这里有很详细的解释,其实我也正在学习中呢。见笑了。

    好的,接着我们开始试验:

    static void Main(string[] args)
            {
                Server s = new Server();//实例化本类
                Assembly ass = s.ComileClass();  //得到程序集
    
                List<Object> df = new List<object>();// 定义一个object的List对象
    
                Dictionary<string, int> tst1 = new Dictionary<string, int>();
                tst1.Add("任贤齐", 23);
                tst1.Add("刘德华", 24);
                tst1.Add("关之琳", 25);
    
                foreach (KeyValuePair<string, int> d in tst1)
                {
                    object obj = ass.CreateInstance("student");//实例化student类
                    obj.GetType().GetProperty("name").SetValue(obj, d.Key, null);//对上面实例化的类的name进行设置
                    obj.GetType().GetProperty("age").SetValue(obj, d.Value, null);//对上面实例化的类age进行设置值
    
                    df.Add(obj);//装进List的集合中。
                }
    
            // 开始列出所有的结果。。。
    foreach (object o in df) { Console.WriteLine(o.GetType().GetProperty("name").GetValue(o, null).ToString()); Console.WriteLine(o.GetType().GetProperty("age").GetValue(o, null).ToString()); } }

    得到的结果如下:

    结束,谢谢大家。

    作者:Lanny☆兰东才
    出处:http://www.cnblogs.com/damonlan
    Q Q:*********
    E_mail:Damon_lan@163.com or Dongcai.lan@hp.com

    本博文欢迎大家浏览和转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,在『参考』的文章中,我会表明参考的文章来源,尊重他人版权。若您发现我侵犯了您的版权,请及时与我联系。

  • 相关阅读:
    Java LinkList遍历方式
    Java LinkedList的实现原理
    ArrayList 原理(2)
    ArrayList 原理(1)
    Java中HashMap的实现原理
    Java HashMap两种遍历方式
    【转】Unity3d:读取FBX中的动画
    C#与U3D中字符串尾0
    U3D中的又一个坑
    MaxScript 学习笔记【有转载】
  • 原文地址:https://www.cnblogs.com/damonlan/p/2986749.html
Copyright © 2020-2023  润新知