国产探花免费观看_亚洲丰满少妇自慰呻吟_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的類生成,倒是不錯

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 文成县| 安宁市| 万荣县| 巴彦淖尔市| 芜湖县| 南木林县| 高要市| 同德县| 安溪县| 鄂托克旗| 鲁甸县| 大姚县| 吉隆县| 泸水县| 潍坊市| 土默特右旗| 吉首市| 临沭县| 通辽市| 兴仁县| 大田县| 鄯善县| 广宁县| 大名县| 老河口市| 敖汉旗| 桐柏县| 昔阳县| 巫溪县| 墨江| 同德县| 丰镇市| 宝应县| 从化市| 剑阁县| 县级市| 杂多县| 广水市| 平阳县| 玉溪市| 贵溪市|