国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

通過Emit實現動態類生成

2024-07-21 02:24:36
字體:
來源:轉載
供稿:網友
動態生成一個類對于aop,o/r mapping等技術非常有幫助。對于java來說,問題不大,而對于.net,則要麻煩些(主要麻煩在于實現代碼的生成需要il),故猜測這可能也是在aop, o/r mapping方面,java走得略前的原因吧。

麻煩歸麻煩,非不能也,動態生成一個簡單的類還不至于太難。

假設有如下接口:
interface ianimal
{
void move();
void eat();
}

希望能創建一個類生成器typecreator,并能以以下方式使用:

typecreator tc=new typecreator(typeof(ianimal));
type t = tc.build();
ianimal myanimal= (ianimal)activator.createinstance(t);
myanimal.move();
myanimal.eat();
首先,發現system.reflection.emit.typebuilder似乎就是一個現成的類生成器。 不過typebuilder既沒有實用的static方法,也不能在外部實例化。不過modulebuilder倒有一個definetype()方法,可以得到typebuilder;而modulebuilder和typerbuilder一個德行,不能直接創建,得從assemblybuilder的definedynamicmodule()方法得到。追根溯源,assemblybuilder得從appdomain的definedynamicassembly()的得來。最終好在appdomain提供了一個靜態方法:appdomain.currentdomain. 這一連串并非沒有道理,類型是依附于module的,而module依附于assembly,而assembly則被appdomain裝載。所謂“皮之不存,毛將焉附”,為了創建type這個“毛”,得先把assembly,module這些“皮”依次構造出來:

using system;
using system.reflection;
using system.reflection.emit;


public class typecreator
{
private type targettype;

/// <summary>
/// 構造函數
/// </summary>
/// <param name="targettype">被實現或者繼承的類型</param>
public typecreator(type targettype)
{
this.targettype = targettype;
}

public type build()
{
//獲取當前appdomain
appdomain currentappdomain = appdomain.currentdomain;

//system.reflection.assemblyname 是用來表示一個assembly的完整名稱的
assemblyname assyname = new assemblyname();

//為要創建的assembly定義一個名稱(這里忽略版本號,culture等信息)
assyname.name = "myassyfor_" + targettype.name;

//獲取assemblybuilder
//assemblybuilderaccess有run,save,runandsave三個取值
assemblybuilder assybuilder = currentappdomain.definedynamicassembly(assyname,assemblybuilderaccess.run);

//獲取modulebuilder,提供string參數作為module名稱,隨便設一個
modulebuilder modbuilder = assybuilder.definedynamicmodule("mymodfor_"+targettype.name);

//新類型的名稱:隨便定一個
string newtypename = "imp_"+targettype.name;

//新類型的屬性:要創建的是class,而非interface,abstract class等,而且是public的
typeattributes newtypeattribute = typeattributes.class | typeattributes.public;

//聲明要創建的新類型的父類型
type newtypeparent;

//聲明要創建的新類型要實現的接口
type[] newtypeinterfaces;

//對于基類型是否為接口,作不同處理
if(targettype.isinterface)
{
newtypeparent = null;
newtypeinterfaces = new type[]{targettype};
}
else
{
newtypeparent = targettype;
newtypeinterfaces = new type[0];
}

//得到類型生成器
typebuilder typebuilder = modbuilder.definetype(newtypename,newtypeattribute,newtypeparent,newtypeinterfaces);

//以下將為新類型聲明方法:新類型應該override基類型的所以virtual方法

//得到基類型的所有方法
methodinfo[] targetmethods = targettype.getmethods();

//遍歷各個方法,對于virtual的方法,獲取其簽名,作為新類型的方法
foreach(methodinfo targetmethod in targetmethods)
{
//只挑出virtual的方法
if(targetmethod.isvirtual)
{
//得到方法的各個參數的類型
parameterinfo[] paraminfo = targetmethod.getparameters();
type[] paramtype = new type[paraminfo.length];
for(int i=0;i<paraminfo.length;i++)
paramtype[i] = paraminfo[i].parametertype;

//傳入方法簽名,得到方法生成器
methodbuilder methodbuilder = typebuilder.definemethod(targetmethod.name,methodattributes.public|methodattributes.virtual,targetmethod.returntype,paramtype);

//由于要生成的是具體類,所以方法的實現是必不可少的。而方法的實現是通過emit il代碼來產生的

//得到il生成器
ilgenerator ilgen = methodbuilder.getilgenerator();
//以下三行相當于:{console.writeln("i'm "+ targetmethod.name +"ing");}
ilgen.emit(opcodes.ldstr,"i'm "+ targetmethod.name +"ing");
ilgen.emit(opcodes.call,typeof(console).getmethod("writeline",new type[]{typeof(string)}));
ilgen.emit(opcodes.ret);
}
}
//真正創建,并返回
return(typebuilder.createtype());
}
}

好了,測試一下試試看:using system;

public class tester
{
public static void main(string[] args)
{
typecreator tc=new typecreator(typeof(ianimal));
type t = tc.build();
ianimal animal= (ianimal)activator.createinstance(t);
animal.move();
animal.eat();

console.read ();
}
}

得到輸出:i'm moveingi'm eating 總結:如果用于aop的話,emit可以動態生成一個裝飾類,相比于基于remoting架構的tp/rp的方法,效率可能要高些,而且還能攔截new操作符。缺點:對于非virtual的方法,似乎無法攔截。用于o/r mapping的類生成,倒是不錯

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洛川县| 张北县| 札达县| 乐业县| 彰化市| 璧山县| 广安市| 漳州市| 临安市| 合水县| 长岭县| 丰城市| 乐昌市| 芒康县| 贵港市| 麻城市| 靖宇县| 滁州市| 双城市| 威信县| 汪清县| 嘉善县| 玉龙| 咸丰县| 邓州市| 遵义市| 卓尼县| 滦平县| 吐鲁番市| 定兴县| 交口县| 寿阳县| 泽库县| 绩溪县| 同心县| 靖安县| 通城县| 江山市| 平遥县| 尉犁县| 佛坪县|