zoukankan      html  css  js  c++  java
  • Emit Vs CodeDom

    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);
    }
    }
    }
  • 相关阅读:
    每日算法-02旋转矩阵
    广搜
    每日算法-01
    洛谷P1162填涂颜色
    队列
    知识网站复习
    mysql索引底层的数据结构和算法
    Java中的类反射
    常见的加密方式
    计算机数制和运算的一点总结.
  • 原文地址:https://www.cnblogs.com/mxy1028/p/1947769.html
Copyright © 2011-2022 走看看