在下面的例子中,我定義了一個事件釋出類Computer,事件訂閱者ComputerManager。Computer釋出了一個OnAction事件,并且該事件在Increase方法被調用時觸發。ComputerManager接收到事件通知時,會将成員字段handleCount增加1.
先看Computer的定義:
.namespace ILTest
{
.class public auto ansi beforefieldinit Computer extends [mscorlib]System.Object
{
//事件對應的委托執行個體
.field private class [ESBasic]ESBasic.CbSimple onAction
//訂閱事件
.method public hidebysig specialname instance void add_onAction(class [ESBasic]ESBasic.CbSimple) cil managed synchronized
{
ldarg.0
dup
ldfld class [ESBasic]ESBasic.CbSimple ILTest.Computer::onAction
ldarg.1
call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
castclass [ESBasic]ESBasic.CbSimple
stfld class [ESBasic]ESBasic.CbSimple ILTest.Computer::onAction
ret
}
//取消訂閱
.method public hidebysig specialname instance void remove_onAction(class [ESBasic]ESBasic.CbSimple) cil managed synchronized
call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
//釋出事件
.event [ESBasic]ESBasic.CbSimple OnAction
.addon instance void ILTest.Computer::add_onAction(class [ESBasic]ESBasic.CbSimple)
.removeon instance void ILTest.Computer::remove_onAction(class [ESBasic]ESBasic.CbSimple)
//******************* Ctor **********************************************
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
//******************* Method ********************************************
.method public hidebysig instance void Increase() cil managed
{
//觸發事件
ldnull
ceq
brtrue.s L_001
callvirt instance void [ESBasic]ESBasic.CbSimple::Invoke()
nop
L_001: ret
}
}
再看ComputerManager實作:
.class public auto ansi beforefieldinit ComputerManager extends [mscorlib]System.Object
{
.field private class [ILTest]ILTest.Computer computer
.field private int32 handleCount
.method public hidebysig specialname rtspecialname instance void .ctor(class [ILTest]ILTest.Computer) cil managed
{
ldarg.0
ldarg.1
stfld class [ILTest]ILTest.Computer ILTest.ComputerManager::computer
ldc.i4.0
stfld int32 ILTest.ComputerManager::handleCount
//調用基類ctor
call instance void [mscorlib]System.Object::.ctor()
//預定事件
ldfld class [ILTest]ILTest.Computer [ILTest]ILTest.ComputerManager::computer
ldftn instance void ILTest.ComputerManager::HandleAction()
newobj instance void [ESBasic]ESBasic.CbSimple::.ctor(object ,native int)//生成委托執行個體需要兩個參數:目标對象和要調用的方法的指針
callvirt instance void ILTest.Computer::add_onAction(class [ESBasic]ESBasic.CbSimple)
ret
.method public hidebysig instance void HandleAction() cil managed
ldfld int32 ILTest.ComputerManager::handleCount
ldc.i4.1
add
stfld int32 ILTest.ComputerManager::handleCount
}
.method public hidebysig instance int32 GetHandleCount() cil managed
}
}
最後,我們寫個Main方法來測試一下:
.class private auto ansi beforefieldinit MainClass
.method public hidebysig static void Main(string[] args) cil managed
.entrypoint
.locals init
(
[0] class [ILTest]ILTest.Computer computer,
[1] class [ILTest]ILTest.ComputerManager computerManager,
[2] int32 count
)
newobj instance void [ILTest]ILTest.Computer::.ctor()
stloc.0
ldloc.0
newobj instance void [ILTest]ILTest.ComputerManager::.ctor(class [ILTest]ILTest.Computer)
stloc.1
ldloc.0
dup
dup
call instance void [ILTest]ILTest.Computer::Increase()
call instance void [ILTest]ILTest.Computer::Increase()
call instance void [ILTest]ILTest.Computer::Increase()
ldloc.1
call instance int32 [ILTest]ILTest.ComputerManager::GetHandleCount()
stloc.2
ldloca.s 2
call instance string [mscorlib]System.Int32::ToString()
call void [mscorlib]System.Console::WriteLine( string )
call string [mscorlib]System.Console::ReadLine( )
pop
ret
main方法中調用了Increase方法三次,表示OnAction事件将被觸發三次,是以運作後輸出的結果是3。
如果你想使用IL進行應用程式開發,那麼我推薦你使用開發環境SharpDevelop,對IL的支援還是不錯的(遺憾的是還不支援對IL的代碼提示),截圖如下:
