亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

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

系統 1998 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條評論
主站蜘蛛池模板: 中文日本在线 | 日韩女人做爰大片 | 日韩高清性爽一级毛片免费 | 亚洲国产精品看片在线观看 | 2018久久久国产精品 | 乱人伦中文字幕在线看 | 欧美123区 | 337p欧美超大胆日本人术艺术 | 久久亚洲精品视频 | 久久精品亚洲欧美va | 四虎免费在线观看 | 狠狠色噜噜狠狠狠狠五月婷 | 国产精品视频男人的天堂 | 国产特黄一级毛片特黄 | 国产成a人片在线观看视频99 | 亚洲国产精品久久 | 日韩欧美一区在线观看 | 久久99热这里只有精品免费看 | 天天干天天舔天天操 | 成人看的午夜免费毛片 | 综合色婷婷 | 亚洲欧美一区在线 | 久热这里只有精品视频6 | 欧美视频在线一区二区三区 | 999成人精品视频在线 | 97在线亚洲 | 亚洲欧美国产高清va在线播放 | 成人亚洲在线观看 | 涩综合 | 九九视频高清视频免费观看 | 久久老色鬼天天综合网观看 | 狠狠色丁香久久婷婷综合五月 | 校园春色男人天堂 | 亚洲精品第一区二区在线 | 国产一级影视 | 综合伊人久久 | 99在线播放视频 | 久久国产加勒比精品无码 | 亚洲午夜国产精品无卡 | 66精品综合久久久久久久 | 一级一级毛片看看 |