欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

基于CodeGenerator的Emit代碼生成輔助類源碼及

系統 2072 0
本文介紹一組NBearV4中的基于Emit動態生成代碼的輔助類,部分概念在本人的blog之前的文章中或多或少都有介紹,這里包含最新的更新及演示、測試。主要是兩個類:CodeGenerator和 DynamicMethodFactory。前者提供了一種經過封裝的,簡化Emit方法(包括Emit DynamicMethod,Constructor,Method,get、set Method of Property)的方案;后者基于前者,實現了一種訪問指定類(可以是第三方程序集的internal類)的方法或成員變量,實例化第三方程序集中的internal類型,高性能的以非泛型語法訪問泛型方法的機制(通過DynamicMethod和Delegate實現)。

下載源碼: NBear.Common.zip

介紹

CodeGenerator

該類很多地方參照了.NET 3.0的System.Runtime.Serialization.dll中的同名internal類,他封裝了Emit中的各種Emit層面的常用操作邏輯,包括Ld各種value、成員變量,if-else,case switch,loop等分支控制等,擴展的版本使用DesignByContract對所有的輸入參數進行了檢查,并擴展了對Emit Constructor,Method,get、set Method of Property的支持。

關于Emit DynamicMethod的示例,大家可以參見稍后介紹的 DynamicMethodFactory 類,這里先給出一個使用該類Emit一個類,并實現一個接口的示例代碼,該示例代碼為包含于源碼的 CodeGenerator .cs文件末尾的UnitTest代碼:

?1 ???? namespace ?CodeGeneratorUnitTest
?2 ???? {
?3 ???????? public ? interface ?ITest
?4 ???????? {
?5 ???????????? string ?Wow( string ?str);
?6 ????????}

?7
?8 ???????? public ? class ?UnitTest
?9 ???????? {
10 ???????????? public ? static ? void ?TestEmitInterface()
11 ???????????? {
12 ????????????????AssemblyName?assName? = ? new ?AssemblyName( " TestEmitInterface " );
13 ????????????????AssemblyBuilder?assBuilder? = ?AppDomain.CurrentDomain.DefineDynamicAssembly(assName,?AssemblyBuilderAccess.Run);
14 ????????????????ModuleBuilder?modBuilder? = ?assBuilder.DefineDynamicModule(assBuilder.GetName().Name);
15 ????????????????TypeBuilder?typeBuilder? = ?modBuilder.DefineType( " TestEmitInterface.TestImpl " ,?TypeAttributes.Public);
16 ????????????????typeBuilder.AddInterfaceImplementation( typeof (ITest));
17
18 ????????????????CodeGenerator?ctor? = ? new ?CodeGenerator(typeBuilder,? " ctor " ,?MethodAttributes.Public,?CallingConventions.Standard,? null ,?Type.EmptyTypes);
19 ????????????????ctor.Ldarg( 0 );
20 ????????????????ctor.Call( typeof ( object ).GetConstructor(Type.EmptyTypes));
21 ????????????????ctor.Ret();
22
23 ????????????????MethodInfo?mi? = ? typeof (ITest).GetMethod( " Wow " );
24
25 ????????????????CodeGenerator?wow? = ? new ?CodeGenerator(typeBuilder,?mi.Name,?mi.Attributes? & ?( ~ MethodAttributes.Abstract)? | ?MethodAttributes.Public,?mi.CallingConvention,?mi.ReturnType,? new ?Type[]? {? typeof ( string )?} );
26 ????????????????wow.Ldarg( 1 );
27 ????????????????wow.Ret();
28
29 ????????????????typeBuilder.DefineMethodOverride(wow.CurrentMethod,?mi);
30
31 ????????????????Type?testImplType? = ?typeBuilder.CreateType();
32 ????????????????ITest?test? = ?(ITest)Activator.CreateInstance(testImplType);
33 ????????????????Check.Assert(test.Wow( " hello " )? == ? " hello " );
34 ????????????}

35 ????????}

36 ????}

以上代碼Emit了一個TestImpl類,它實現了ITest接口,包含一個默認構造函數和一個Wow方法,注意,構造函數和方法都是通過CodeGenerator Emit的,這里的邏輯比較簡單,但應該已經能看到相對于ilGen.Emit(OpCodes.XXX, YYY)這樣的語法的簡化,如果實現邏輯復雜,對整個Emit過程的簡化就更明顯。

DynamicMethodFactory

該類的主要功能包括:實例化第三方程序集中的internal類型( DynamicMethodFactory. CreateInstance()方法),為指定類型(可以是第三方程序集中的internal類型)的泛型或非泛型方法、屬性、字段的讀寫生成非強類型的Delegate(通過DynamicMethod實現,不使用反射,性能接近直接訪問)。

下面先給出一個該類中為一個Method創建一個DynamicMethod,并返回其Delegate的示例,DynamicMethod是使用前面介紹的CodeGenerator實現的:

?1 ???????? protected ? static ?DynamicMethodProxyHandler?DoGetMethodDelegate(
?2 ????????????Module?targetModule,
?3 ????????????MethodInfo?genericMethodInfo,
?4 ???????????? params ?Type[]?genericParameterTypes)
?5 ???????? {
?6 ???????????? Check?preconditions
16
17 ???????????? // Create?a?dynamic?method?proxy?delegate?used?to?call?the?specified?methodinfo
18 ????????????CodeGenerator?gen? = ? new ?CodeGenerator(targetModule);
19 ????????????gen.BeginMethod( " dm " ? + ?Guid.NewGuid().ToString( " N " ),? typeof (DynamicMethodProxyHandler));
20 ????????????MethodInfo?makeGenericMethodInfo? = ?MakeMethodGeneric(genericMethodInfo,?genericParameterTypes);
21 ????????????gen.Ldarg( 0 );
22 ????????????LoadParameters(gen,?makeGenericMethodInfo.GetParameters(),? false );
23 ????????????gen.Call(makeGenericMethodInfo);
24 ????????????CastValueToObject(gen,?makeGenericMethodInfo.ReturnType);
25
26 ???????????? return ?(DynamicMethodProxyHandler)gen.EndMethod();
27 ????????}

LoadParameters和CastValueToObject的代碼

代碼是不是相對比較簡單呢(當然是相對于自己寫所有的Emit來講的),注意這里的LoadParameter方法的實現您可以發現,為方法生成調用Delegate是完美支持輸入輸出參數的。

下面給出
DynamicMethodFactory類的UnitTest代碼,演示了對方法、字段和屬性的生成Delegate和基于Delegate的讀寫,且包括對輸入輸出參數的使用:

??1 ???? namespace ?DynamicMethodFactoryUnitTest
??2 ???? {
??3 ???????? public ? class ?TestClass
??4 ???????? {
??5 ???????????? public ? static ? void ?StaticReturnVoidMethod()
??6 ???????????? {
??7 ????????????}

??8
??9 ???????????? public ? static ? int ?StaticReturnIntMethod( string ?str,? int ?i,? ref ? int ?refInt,? ref ? string ?refStr)
?10 ???????????? {
?11 ????????????????Check.Assert(str? == ? " str " );
?12 ????????????????Check.Assert(i? == ? 1 );
?13 ????????????????Check.Assert(refInt? == ? 3 );
?14 ????????????????Check.Assert(refStr? == ? " instr " );
?15
?16 ???????????????? int ?ret? = ?i? + ?refInt;
?17 ????????????????refInt? = ?i? + ? 1 ;
?18 ????????????????refStr? = ? " ref " ? + ?str;
?19
?20 ????????????????Check.Assert(refInt? == ? 2 );
?21 ????????????????Check.Assert(ret? == ? 4 );
?22 ????????????????Check.Assert(refStr? == ? " refstr " );
?23
?24 ???????????????? return ?ret;
?25 ????????????}

?26
?27 ???????????? public ? static ? int ?StaticIntField;
?28
?29 ???????????? public ? static ? int ?StaticIntProperty
?30 ???????????? {
?31 ???????????????? get
?32 ???????????????? {
?33 ???????????????????? return ?StaticIntField;
?34 ????????????????}

?35 ???????????????? set
?36 ???????????????? {
?37 ????????????????????StaticIntField? = ?value;
?38 ????????????????}

?39 ????????????}

?40
?41 ???????????? public ? void ?NonStaticReturnVoidMethod()
?42 ???????????? {
?43 ????????????}

?44
?45 ???????????? public ? int ?NonStaticReturnIntMethod( string ?str,? int ?i,? out ? int ?outInt,? out ? string ?outStr)
?46 ???????????? {
?47 ????????????????outInt? = ?i? + ? 1 ;
?48 ????????????????Check.Assert(outInt? == ? 2 );
?49 ????????????????outStr? = ? " out " ? + ?str;
?50 ????????????????Check.Assert(outStr? == ? " outstr " );
?51 ???????????????? return ?i? + ? 2 ;
?52 ????????????}

?53
?54 ???????????? public ? int ?NonStaticIntField;
?55
?56 ???????????? public ? int ?NonStaticIntProperty
?57 ???????????? {
?58 ???????????????? get
?59 ???????????????? {
?60 ???????????????????? return ?NonStaticIntField;
?61 ????????????????}

?62 ???????????????? set
?63 ???????????????? {
?64 ????????????????????NonStaticIntField? = ?value;
?65 ????????????????}

?66 ????????????}

?67 ????????}

?68
?69 ???????? public ? class ?UnitTest
?70 ???????? {
?71 ???????????? private ? static ?DynamicMethodFactory?fac? = ? new ?DynamicMethodFactory();
?72
?73 ???????????? public ? static ? void ?TestStaticMethod()
?74 ???????????? {
?75 ????????????????StaticDynamicMethodProxyHandler?handler? = ?fac.GetStaticMethodDelegate( typeof (TestClass).GetMethod( " StaticReturnVoidMethod " ));
?76 ????????????????handler( null );
?77
?78 ???????????????? object []?inputParams? = ? new ? object []? {? " str " ,? 1 ,? 3 ,? " instr " ?} ;
?79 ????????????????handler? = ?fac.GetStaticMethodDelegate( typeof (TestClass).GetMethod( " StaticReturnIntMethod " ));
?80 ???????????????? object ?ret? = ?handler(inputParams);
?81 ????????????????Check.Assert((( int )inputParams[ 2 ])? == ? 2 );
?82 ????????????????Check.Assert((( string )inputParams[ 3 ])? == ? " refstr " );
?83 ????????????????Check.Assert((( int )ret)? == ? 4 );
?84 ????????????}

?85
?86 ???????????? public ? static ? void ?TestStaticField()
?87 ???????????? {
?88 ????????????????TestClass.StaticIntField? = ? - 1 ;
?89 ????????????????FieldInfo?field? = ? typeof (TestClass).GetField( " StaticIntField " );?;
?90 ????????????????StaticDynamicMethodProxyHandler?handler? = ?fac.GetStaticFieldSetDelegate(field);
?91 ????????????????handler( new ? object []? {? 5 ?} );
?92 ????????????????Check.Assert(TestClass.StaticIntField? == ? 5 );
?93 ????????????????handler? = ?fac.GetStaticFieldGetDelegate(field);
?94 ????????????????Check.Assert((( int )handler( null ))? == ? 5 );
?95 ????????????}

?96
?97 ???????????? public ? static ? void ?TestStaticProperty()
?98 ???????????? {
?99 ????????????????TestClass.StaticIntField? = ? - 1 ;
100 ????????????????PropertyInfo?property? = ? typeof (TestClass).GetProperty( " StaticIntProperty " );?;
101 ????????????????StaticDynamicMethodProxyHandler?handler? = ?fac.GetStaticMethodDelegate(property.GetSetMethod());
102 ????????????????handler( new ? object []? {? 5 ?} );
103 ????????????????Check.Assert(TestClass.StaticIntProperty? == ? 5 );
104 ????????????????handler? = ?fac.GetStaticMethodDelegate(property.GetGetMethod());
105 ????????????????Check.Assert((( int )handler( null ))? == ? 5 );
106 ????????????}

107
108 ???????????? public ? static ? void ?TestNonStaticMethod()
109 ???????????? {
110 ????????????????TestClass?obj? = ? new ?TestClass();
111
112 ????????????????DynamicMethodProxyHandler?handler? = ?fac.GetMethodDelegate( typeof (TestClass).GetMethod( " NonStaticReturnVoidMethod " ));
113 ????????????????handler(obj,? null );
114
115 ???????????????? object []?inputParams? = ? new ? object []? {? " str " ,? 1 ,? null ,? null ?} ;
116 ????????????????handler? = ?fac.GetMethodDelegate( typeof (TestClass).GetMethod( " NonStaticReturnIntMethod " ));
117 ???????????????? object ?ret? = ?handler(obj,?inputParams);
118 ????????????????Check.Assert((( int )inputParams[ 2 ])? == ? 2 );
119 ????????????????Check.Assert((( string )inputParams[ 3 ])? == ? " outstr " );
120 ????????????????Check.Assert((( int )ret)? == ? 3 );
121 ????????????}

122
123 ???????????? public ? static ? void ?TestNonStaticField()
124 ???????????? {
125 ????????????????TestClass?obj? = ? new ?TestClass();
126 ????????????????obj.NonStaticIntField? = ? - 1 ;
127
128 ????????????????FieldInfo?field? = ? typeof (TestClass).GetField( " NonStaticIntField " );?;
129 ????????????????DynamicMethodProxyHandler?handler? = ?fac.GetFieldSetDelegate(field);
130 ????????????????handler(obj,? new ? object []? {? 5 ?} );
131 ????????????????Check.Assert(obj.NonStaticIntField? == ? 5 );
132 ????????????????handler? = ?fac.GetFieldGetDelegate(field);
133 ????????????????Check.Assert((( int )handler(obj,? null ))? == ? 5 );
134 ????????????}

135
136 ???????????? public ? static ? void ?TestNonStaticProperty()
137 ???????????? {
138 ????????????????TestClass?obj? = ? new ?TestClass();
139 ????????????????obj.NonStaticIntField? = ? - 1 ;
140
141 ????????????????PropertyInfo?property? = ? typeof (TestClass).GetProperty( " NonStaticIntProperty " );?;
142 ????????????????DynamicMethodProxyHandler?handler? = ?fac.GetMethodDelegate(property.GetSetMethod());
143 ????????????????handler(obj,? new ? object []? {? 5 ?} );
144 ????????????????Check.Assert(obj.NonStaticIntField? == ? 5 );
145 ????????????????handler? = ?fac.GetMethodDelegate(property.GetGetMethod());
146 ????????????????Check.Assert((( int )handler(obj,? null ))? == ? 5 );
147 ????????????}

148 ????????}

149 ????}

DynamicMethodFactory類還可以用于以非泛型方法的調用語法調用泛型方法,在之前的一篇文章介紹過,這里就不重復了,感興趣的朋友可以參見: 改進的 以非泛型方式調用泛型方法”之基于DynamicMethod的實現

有任何問題歡迎回復討論。

//The End

基于CodeGenerator的Emit代碼生成輔助類源碼及演示


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久精品视频99 | 这里只有精品在线视频观看 | 国产精品久久国产精品 | 亚洲国产精品一区二区久久 | 国产亚洲欧洲国产综合一区 | 欧美亚洲黄色 | 亚洲欧美另类色妞网站 | www.99精品视频在线播放 | 日本在线播放不卡一区二区三区 | 精品一区二区三区免费站 | 青青久热 | 天天色播 | 99久久免费观看 | 思瑞在线观看 | 欧美人成在线 | 国产精品久久久久久久久免费 | 看黄色毛片 | 黄色一级小视频 | 国产三级在线 | 成人在线免费观看 | 国产精品日本欧美一区二区 | 国产欧美日韩综合精品一区二区 | 日韩有码一区二区三区 | 日本免费一级视频 | 国产喷水视频 | 一级毛片男女做受 | 哥斯拉大战金刚2在线观看免费完整版 | 成人欧美s视频在线观看 | 亚洲精品视频一区 | 免费无码毛片一区二区A片 成人18网站 | 亚洲精品婷婷无码成人A片在线 | 午夜精品在线观看 | 成人精品国产 | 久久久久久网站 | 日韩1页 | 天天操夜夜艹 | 久久这里只有精品99 | 欧美一区久久久 | 超碰伊人网 | 成人性爱视频在线观看 | 夜夜爱网站|