動(dòng)態(tài)方法與動(dòng)態(tài)代理(上篇)
2011-06-22 14:57 熬夜的蟲子 閱讀(640) 評(píng)論(0) 收藏 舉報(bào)所謂動(dòng)態(tài)方法,是指在程序運(yùn)行階段生成的并且能夠執(zhí)行的方法. 動(dòng)態(tài)方法可以關(guān)聯(lián)到任何已有的模塊(Module)中,作為現(xiàn)有模塊的擴(kuò)展. 動(dòng)態(tài)方法可以訪問模塊中所有類型及其成員.
實(shí)現(xiàn)動(dòng)態(tài)方法依賴于:反射發(fā)出(System.Reflection.Emit)、 MSIL語言

String.ToLower()方法的MSIL代碼
|
操作指令 |
說明 |
|
ldarg |
將參數(shù)加載到堆棧頂部 例如:ldarg.0 將第一個(gè)參數(shù)加載到堆棧 |
|
starg |
將棧頂元素保存到參數(shù) 例如:starg.0 將棧頂數(shù)據(jù)保存到第一個(gè)參數(shù) |
|
ldloc |
將本地變量加載到堆棧頂部 例如:ldloc.0 將第一個(gè)變量加載到堆棧 |
|
stloc |
將棧頂元素保存到本地變量 例如:stloc.0 將棧頂數(shù)據(jù)保存到第一個(gè)變量 |
|
ldc |
將常量數(shù)字加載到堆棧頂部 例如:ldc.i4.2 將2加載到堆棧,i4表示int32數(shù)字 |
|
類似的還有用于加載字符串的ldstr、加載和保存字段的ldfld和stfld、加載數(shù)字常量的ldc等等,這些指令執(zhí)行的操作很好記,以ld開頭的就是加載到堆棧,以st開頭的就是從堆棧上取回值 | |
|
call callvirt |
作用都是調(diào)用方法,但用法有區(qū)別:call用于執(zhí)行非虛函數(shù)或靜態(tài)方法;callvirt用于執(zhí)行虛函數(shù)或?qū)嵗椒ǎ⒁?,這里所說的是一般情況,編譯器為了優(yōu)化也有例外。 |
|
ret |
方法返回,如果有返回值,則將其從被調(diào)者堆棧轉(zhuǎn)移到調(diào)用者堆棧頂部 |
|
nop |
空操作 |
|
br |
無條件跳轉(zhuǎn),br.s是br的短格式 例如:br.s L_0002 無條件跳轉(zhuǎn)到L_0002行 |
|
brtrue |
操作數(shù)非空或非False時(shí)跳轉(zhuǎn) 例如:brtrue.s L_0002 當(dāng)操作數(shù)為真時(shí)跳轉(zhuǎn)到L_0002行 |
|
brfalse |
操作數(shù)為空、為False或?yàn)?時(shí)跳轉(zhuǎn) 例如:brfalse.s L_0002 當(dāng)操作數(shù)為假時(shí)跳轉(zhuǎn)到L_0002行 |
|
相關(guān)的跳轉(zhuǎn)語言還有beq、bge、ble和blt等等,執(zhí)行跳轉(zhuǎn)語言后,堆棧元素將被清除,即堆棧頂部不包含元素,b和br都是branch的縮寫 | |
|
add |
將兩個(gè)操作數(shù)相加,結(jié)果放到堆棧頂部 |
|
sub |
將兩個(gè)操作數(shù)相減,結(jié)果放到堆棧頂部 |
?反射發(fā)出
反射發(fā)出不是將文本形式的C#代碼編譯成DLL
{
static void Main(string[] args)
{
Type[] paramTypes = new Type[] { typeof(string) };
DynamicMethod hello = new DynamicMethod("Hello", null, paramTypes, typeof(Program).Module);
ILGenerator ilGen = hello.GetILGenerator();
ilGen.Emit(OpCodes.Ldarg_0);
MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
ilGen.Emit(OpCodes.Call, writeLineMethod);
ilGen.Emit(OpCodes.Ret);
Action<string> invoker = (Action<string>)hello.CreateDelegate(typeof(Action<string>));
invoker("你好,我來自于動(dòng)態(tài)方法");
}
}
![]() |
原創(chuàng)作品允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處以及作者信息。 作者:熬夜的蟲子 點(diǎn)擊查看:博文索引 |

浙公網(wǎng)安備 33010602011771號(hào)