• NET


    Emit Vs CodeDom

    https://www.cnblogs.com/mxy1028/archive/2011/01/30/1947769.html

    namespace

    • System.CodeDom;
    • System.Reflection;
    • System.Reflection.Emit;
    • Microsoft.CSharp;
    • System.CodeDom.Compiler;
    • System.Globalization;

    Emit 和 CodeDom 都是用来动态创建类型,并利用反射执行的东东~~~~ 这两个都是 .NET Framework 中比较有深度的内容。

    有关 CodeDom,雨痕已经写过好几篇了,此处不再详述。CodeDom 利用 C#/VB.NET 等编译引擎进行动态编译,而 Emit 则直接使用 IL,从编程方便的角度来说 CodeDom 更方便一点。当然 CodeDom 要花费一定的编译时间,而一旦载入则和 Emit 或静态编译程序集没有什么区别。Emit 被很多 AOP/ORM 组件所使用,除了 ILGenerator 外,和 CodeDom 的编程习惯很相似。接下来雨痕会写几篇 Emit 的使用文章。

    好了,从经典的 "Hello, World!" 开始。我们本次的目标是用 Emit 重写下面的类型,并完成动态调用。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.CodeDom;
    using System.Reflection;
    using System.Reflection.Emit;
    using Microsoft.CSharp;
    using System.CodeDom.Compiler;
    using System.Globalization;
    
    namespace ConsoleApplication5
    {
        /// <summary>
        /// Emit 和 CodeDom 都是用来动态创建类型,并利用反射执行的东东~~~~ 
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                /*
                //一,Emit 则直接使用 IL
                //1. 定义动态程序集
                AssemblyName assemblyName = new AssemblyName("Nettip.Assembly");
                AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
    
                //2. 定义动态模块
                ModuleBuilder module = assembly.DefineDynamicModule("Nettip.QueryOrderConditon.Module");
    
                //3. 定义类型
                TypeBuilder type = module.DefineType("QueryOrderCondition", TypeAttributes.Class, typeof(object));
    
                //4. 定义方法
                MethodBuilder method = type.DefineMethod("Test", MethodAttributes.Public, CallingConventions.HasThis, null, null);
    
                //5. 方法代码
                ILGenerator il = method.GetILGenerator();
                il.Emit(OpCodes.Nop);
                il.Emit(OpCodes.Ldstr, "Hello, World!");
                il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
                il.Emit(OpCodes.Nop);
                il.Emit(OpCodes.Ret);
    
                //6. 执行
                Type class1 = type.CreateType();
                object o = Activator.CreateInstance(class1);
                o.GetType().GetMethod("Test").Invoke(o, null);
                */
                //二,CodeDom 利用 C#/VB.NET 等编译引擎进行动态编译
    
                #region
                // 1. 使用CodeDom创建源码
                //CodeCompileUnit cu = new CodeCompileUnit();
                //CodeNamespace Samples = new CodeNamespace("Samples");
                //cu.Namespaces.Add(Samples); 
                //Samples.Imports.Add(new CodeNamespaceImport("System"));             
                //CodeTypeDeclaration Class1 = new CodeTypeDeclaration("Class1"); 
                //Samples.Types.Add(Class1); 
                //CodeEntryPointMethod Start = new CodeEntryPointMethod(); 
                //CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(  
                //    new CodeTypeReferenceExpression("System.Console"), "WriteLine", 
                //    new CodePrimitiveExpression("Hello World!") );
                //Start.Statements.Add(new CodeExpressionStatement(cs1));
                //Class1.Members.Add(Start); 
    
                string code = @"
                    using System;
                    namespace Nettip
                    {
                        public class QueryOrderCondition
                        
                            private string name;
    
                            public QueryOrderCondition(string name)
                            {
                                this.name = name;
                            }
    
                            public void Test()
                            {
                                Console.WriteLine(""{0} - {1}"", name, DateTime.Now);
                            }
                        }
                    }
                ";
    
                #endregion
                //1. 创建编译器对象
                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
    
                //2. 设置编译参数
                CompilerParameters cp = new CompilerParameters();
                cp.ReferencedAssemblies.Add("System.dll");
                cp.GenerateInMemory = false;
                cp.OutputAssembly = "Nettip.QueryOrderCondition.dll";
    
                //3. 开始编译
                CompilerResults results = provider.CompileAssemblyFromSource(cp, code);
                //3.1 显示编译信息
                if (results.Errors.Count == 0)
                    Console.WriteLine(""{0}" compiled ok!", results.CompiledAssembly.Location);
                else
                {
                    Console.WriteLine("Complie Error:");
                    foreach (CompilerError error in results.Errors)
                        Console.WriteLine("  {0}", error);
                }
    
                //4.执行
                Type t = results.CompiledAssembly.GetType("Nettip.QueryOrderCondition");
                object o = results.CompiledAssembly.CreateInstance("Nettip.QueryOrderCondition", false, BindingFlags.Default,
                    null, new object[] { "Tom" }, CultureInfo.CurrentCulture, null);
                t.InvokeMember("Test", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
                    null, o, null);
            }
        }
    }
    
    
  • 相关阅读:
    线性DP
    2020年第十一届蓝桥杯第二场C/C++ B组省赛题解
    筛质数 + 质因子分解
    快速幂
    DP 背包问题
    CF510B Fox And Two Dots
    怎样看人生的价值和意义!--找回迷失的自己
    Ionic+AngularJS 开发的页面在微信公众号下显示不出来原因查究
    AngularJS directive 指令相关记录
    AngularJS的一点学习笔记
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/9835570.html
走看看 - 开发者的网上家园