程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 基礎才是重中之重~Emit動態構建方法(參數和返回值),之重emit

基礎才是重中之重~Emit動態構建方法(參數和返回值),之重emit

編輯:關於.NET

基礎才是重中之重~Emit動態構建方法(參數和返回值),之重emit


回到目錄

對於Emit我們知道它的可以動態構建程序集,類型,方法,屬性等,或者說只要手動使用C#創建的東西使用Emit也都可以動態創建它們,Emit由於它的特別之處,所以在很多領域得到了廣泛的應用,像最近比較火的AOP技術,它最核心的功能就是方法攔截了,我們使用Emit也是可以實現方法攔截功能的,詳細可以看大叔這篇文章《Lind.DDD.Aspects通過Plugins實現方法的動態攔截~Lind裡的AOP》。

有參數,沒有返回值的方法構建與調用

        [TestMethod]
        public void BulidMethod()
        {
            //得到當前的應用程序域
            AppDomain appDm = AppDomain.CurrentDomain;
            //初始化AssemblyName的一個實例
            AssemblyName an = new AssemblyName();
            //設置程序集的名稱
            an.Name = "EmitLind";
            //動態的在當前應用程序域創建一個應用程序集
            AssemblyBuilder ab = appDm.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            //動態在程序集內創建一個模塊
            ModuleBuilder mb = ab.DefineDynamicModule("EmitLind");
            //動態的在模塊內創建一個類
            TypeBuilder tb = mb.DefineType("HelloEmit", TypeAttributes.Public | TypeAttributes.Class);
            //動態的為類裡創建一個方法
            MethodBuilder mdb = tb.DefineMethod("HelloWord", MethodAttributes.Public, null, new Type[] { typeof(string) });

            //得到該方法的ILGenerator
            ILGenerator ilG = mdb.GetILGenerator();
            ilG.Emit(OpCodes.Ldstr, "Hello:{0}");
            //加載傳入方法的參數到堆棧
            ilG.Emit(OpCodes.Ldarg_1);
            //調用Console.WriteLine方法,輸出傳入的字符
            ilG.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(string) }));

            ilG.Emit(OpCodes.Ret);
            //創建類的Type對象
            Type tp = tb.CreateType();
            //實例化一個類
            object ob = Activator.CreateInstance(tp);
            //得到類中的方法,通過Invoke來觸發方法的調用..
            MethodInfo mdi = tp.GetMethod("HelloWord");
            mdi.Invoke(ob, new object[] { "Hello Lind" });
        }

有參數,同時有返回值的方法構建與調用

        public void BulidMethodRet()
        {

            //得到當前的應用程序域
            AppDomain appDm = AppDomain.CurrentDomain;
            //初始化AssemblyName的一個實例
            AssemblyName an = new AssemblyName();
            //設置程序集的名稱
            an.Name = "EmitLind";
            //動態的在當前應用程序域創建一個應用程序集
            AssemblyBuilder ab = appDm.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            //動態在程序集內創建一個模塊
            ModuleBuilder mb = ab.DefineDynamicModule("EmitLind");
            //動態的在模塊內創建一個類
            TypeBuilder tb = mb.DefineType("HelloEmit", TypeAttributes.Public | TypeAttributes.Class);
          
            //動態的為類裡創建一個方法
            MethodBuilder mdb = tb.DefineMethod(
                "HelloWorldReturn",
                MethodAttributes.Public,
                typeof(string),
                new Type[] { typeof(string), typeof(string) });

            //得到該方法的ILGenerator
            ILGenerator ilG = mdb.GetILGenerator();
            ilG.Emit(OpCodes.Ldstr, "你好:{0}-{1}");
            //加載傳入方法的參數到堆棧
            ilG.Emit(OpCodes.Ldarg_1); 
            ilG.Emit(OpCodes.Ldarg_2);
            //調用Console.WriteLine方法,輸出傳入的字符
            ilG.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(string) ,typeof(string)}));

            // ilG.Emit(OpCodes.Pop);//加這個就有問題了
            //返回值部分
            LocalBuilder local = ilG.DeclareLocal(typeof(string));
            ilG.Emit(OpCodes.Ldstr, "Return Value:{0}");
            ilG.Emit(OpCodes.Ldarg_1);
            ilG.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(string) }));
            ilG.Emit(OpCodes.Stloc_0, local);
            ilG.Emit(OpCodes.Ldloc_0, local);
            ilG.Emit(OpCodes.Ret);
            //創建類的Type對象
            Type tp = tb.CreateType();
            //實例化一個類
            object ob = Activator.CreateInstance(tp);
            //得到類中的方法,通過Invoke來觸發方法的調用..
            MethodInfo mdi = tp.GetMethod("HelloWorldReturn");
            mdi.Invoke(ob, new object[] { "Hello Lind","OK" });
        }

回到目錄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved