C#中反射的使用(How to use reflect in CSharp)(3)Emit的使用

來源:互聯網
上載者:User

標籤:

Emit意在動態構建一個可以執行(當然也就可以反射)或者只可以反射的動態庫。

個人認為在不得不使用反射的情況下,使用Emit會使得效率提升空間很大。亦或者動態外掛程式模式的軟體設計中會用到。

依然2%的廢話和98%的代碼:

 1 using System; 2 using System.Reflection; 3 using System.Reflection.Emit; 4  5 namespace ReflectionTest 6 { 7     class Program 8     { 9         static void Main(string[] args)10         {11             //Emit12             /*13              Emit的知識隸屬於反射的一部分,也是比較偏門的一部分。14              在出現Dynamic和匿名類之後,它會有更小的用武之地,但仍然屬於Reflection的知識範疇。15              區別於“正常”的反射,Emit是動態構建一個類,16              比如,現在你沒有Person.Dll,沒有項目可以引用,沒有可以反射的對象17              那麼你可能會想到Emit,它可以使你用代碼構建出一個Person類,你甚至可以把動態構建的類儲存成DLL,然後使用反射調用18              雖然也是用C#去實現,但文法風格大不相同,強硬的理解,可以理解Emit暴漏給C#一些介面,讓你去操作IL,然後產生動態庫19              在這次的blog中,我們的目的就是用代碼構建出這個person類。OK,Let‘s start20              */21             //STEP 1. Give him a name22             var assemblyName = new AssemblyName("PersonMoudle");23 24             //STEP 2. Build a assembly25             var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,26                 AssemblyBuilderAccess.RunAndSave);27 28             //STEP 3. Add a moudle29             var moudle = assemblyBuilder.DefineDynamicModule("PersonMoudle", "PersonMoudle.dll");30 31             //SETP 4. Add a Class32             var typePart = moudle.DefineType("Person", TypeAttributes.Public);33 34             //SETP 5. Add a method for this Class35             var methodPart = typePart.DefineMethod("SayHi", MethodAttributes.Public, null, null);36 37             //STEP 6. Imp the method38             var il = methodPart.GetILGenerator();39             il.EmitWriteLine("Hi! I‘m SayHi method!");40             il.Emit(OpCodes.Ret);41 42             typePart.CreateType();43             assemblyBuilder.Save("PersonMoudle.dll");44 45             //再比如,構建一個exe46             var ad = AppDomain.CurrentDomain;47             var am = new AssemblyName {Name = "TestEmit"};48             var ab = ad.DefineDynamicAssembly(am, AssemblyBuilderAccess.Save);49             var mb = ab.DefineDynamicModule("testmod", "輸出一句話.exe");50             var tb = mb.DefineType("TestEmit.Test", TypeAttributes.Public);51             var metb = tb.DefineMethod("ConsoleWord", MethodAttributes.Public | MethodAttributes.Static, typeof (void),52                 null);53             ab.SetEntryPoint(metb);54             ILGenerator il1 = metb.GetILGenerator();55             il1.EmitWriteLine("Hello World");56             il1.EmitWriteLine("按任意鍵退出……");57             il1.Emit(OpCodes.Call, typeof (Console).GetMethod("ReadKey",new Type[]{}));//指定無參數的重載。生產環境的代碼中應該有更加嚴格判斷,具體指定個某個方法請翻前篇的文章。58             il1.Emit(OpCodes.Ret);59             tb.CreateType();60             ab.Save("輸出一句話.exe");61             Console.ReadKey();62         }63     }64 }

我們可以看到,執行完這個之後,在Debug裡會產生我們想要的PersonMoudle.dll和輸出一句話.exe、反編譯後的dll和exe的執行效果:

 

C#中反射的使用(How to use reflect in CSharp)(3)Emit的使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.