在下面的例子中,我定义了一个事件发布类Computer,事件订阅者ComputerManager。Computer发布了一个OnAction事件,并且该事件在Increase方法被调用时触发。ComputerManager接收到事件通知时,会将成员字段handleCount增加1.
先看Computer的定义:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
.
namespace
ILTest
{
. class public autoansibeforefieldinitComputerextends[mscorlib]System.Object
{
// 事件对应的委托实例
.field private class [ESBasic]ESBasic.CbSimpleonAction
// 订阅事件
.method public hidebysigspecialnameinstance void add_onAction( class [ESBasic]ESBasic.CbSimple)cilmanagedsynchronized
{
ldarg. 0
dup
ldfld class [ESBasic]ESBasic.CbSimpleILTest.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.CbSimpleILTest.Computer::onAction
ret
}
// 取消订阅
.method public hidebysigspecialnameinstance void remove_onAction( class [ESBasic]ESBasic.CbSimple)cilmanagedsynchronized
{
ldarg. 0
dup
ldfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
ldarg. 1
call class [mscorlib]System.Delegate[mscorlib]System.Delegate::Remove( class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
castclass[ESBasic]ESBasic.CbSimple
stfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
ret
}
// 发布事件
. event [ESBasic]ESBasic.CbSimpleOnAction
{
.addoninstance void ILTest.Computer::add_onAction( class [ESBasic]ESBasic.CbSimple)
.removeoninstance void ILTest.Computer::remove_onAction( class [ESBasic]ESBasic.CbSimple)
}
// *******************Ctor**********************************************
.method public hidebysigspecialnamertspecialnameinstance void .ctor()cilmanaged
{
ldarg. 0
callinstance void [mscorlib]System.Object::.ctor()
ret
}
// *******************Method********************************************
.method public hidebysiginstance void Increase()cilmanaged
{
// 触发事件
ldarg. 0
ldfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
ldnull
ceq
brtrue.sL_001
ldarg. 0
ldfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
callvirtinstance void [ESBasic]ESBasic.CbSimple::Invoke()
nop
L_001:ret
}
}
}
{
. class public autoansibeforefieldinitComputerextends[mscorlib]System.Object
{
// 事件对应的委托实例
.field private class [ESBasic]ESBasic.CbSimpleonAction
// 订阅事件
.method public hidebysigspecialnameinstance void add_onAction( class [ESBasic]ESBasic.CbSimple)cilmanagedsynchronized
{
ldarg. 0
dup
ldfld class [ESBasic]ESBasic.CbSimpleILTest.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.CbSimpleILTest.Computer::onAction
ret
}
// 取消订阅
.method public hidebysigspecialnameinstance void remove_onAction( class [ESBasic]ESBasic.CbSimple)cilmanagedsynchronized
{
ldarg. 0
dup
ldfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
ldarg. 1
call class [mscorlib]System.Delegate[mscorlib]System.Delegate::Remove( class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
castclass[ESBasic]ESBasic.CbSimple
stfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
ret
}
// 发布事件
. event [ESBasic]ESBasic.CbSimpleOnAction
{
.addoninstance void ILTest.Computer::add_onAction( class [ESBasic]ESBasic.CbSimple)
.removeoninstance void ILTest.Computer::remove_onAction( class [ESBasic]ESBasic.CbSimple)
}
// *******************Ctor**********************************************
.method public hidebysigspecialnamertspecialnameinstance void .ctor()cilmanaged
{
ldarg. 0
callinstance void [mscorlib]System.Object::.ctor()
ret
}
// *******************Method********************************************
.method public hidebysiginstance void Increase()cilmanaged
{
// 触发事件
ldarg. 0
ldfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
ldnull
ceq
brtrue.sL_001
ldarg. 0
ldfld class [ESBasic]ESBasic.CbSimpleILTest.Computer::onAction
callvirtinstance void [ESBasic]ESBasic.CbSimple::Invoke()
nop
L_001:ret
}
}
}
再看ComputerManager实现:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
.
namespace
ILTest
{
. class public autoansibeforefieldinitComputerManagerextends[mscorlib]System.Object
{
.field private class [ILTest]ILTest.Computercomputer
.field private int32handleCount
.method public hidebysigspecialnamertspecialnameinstance void .ctor( class [ILTest]ILTest.Computer)cilmanaged
{
ldarg. 0
ldarg. 1
stfld class [ILTest]ILTest.ComputerILTest.ComputerManager::computer
ldarg. 0
ldc.i4. 0
stfldint32ILTest.ComputerManager::handleCount
// 调用基类ctor
ldarg. 0
callinstance void [mscorlib]System.Object::.ctor()
// 预定事件
ldarg. 0
ldfld class [ILTest]ILTest.Computer[ILTest]ILTest.ComputerManager::computer
ldarg. 0
ldftninstance void ILTest.ComputerManager::HandleAction()
newobjinstance void [ESBasic]ESBasic.CbSimple::.ctor( object ,native int ) // 生成委托实例需要两个参数:目标对象和要调用的方法的指针
callvirtinstance void ILTest.Computer::add_onAction( class [ESBasic]ESBasic.CbSimple)
ret
}
.method public hidebysiginstance void HandleAction()cilmanaged
{
ldarg. 0
dup
ldfldint32ILTest.ComputerManager::handleCount
ldc.i4. 1
add
stfldint32ILTest.ComputerManager::handleCount
ret
}
.method public hidebysiginstanceint32GetHandleCount()cilmanaged
{
ldarg. 0
ldfldint32ILTest.ComputerManager::handleCount
ret
}
}
}
{
. class public autoansibeforefieldinitComputerManagerextends[mscorlib]System.Object
{
.field private class [ILTest]ILTest.Computercomputer
.field private int32handleCount
.method public hidebysigspecialnamertspecialnameinstance void .ctor( class [ILTest]ILTest.Computer)cilmanaged
{
ldarg. 0
ldarg. 1
stfld class [ILTest]ILTest.ComputerILTest.ComputerManager::computer
ldarg. 0
ldc.i4. 0
stfldint32ILTest.ComputerManager::handleCount
// 调用基类ctor
ldarg. 0
callinstance void [mscorlib]System.Object::.ctor()
// 预定事件
ldarg. 0
ldfld class [ILTest]ILTest.Computer[ILTest]ILTest.ComputerManager::computer
ldarg. 0
ldftninstance void ILTest.ComputerManager::HandleAction()
newobjinstance void [ESBasic]ESBasic.CbSimple::.ctor( object ,native int ) // 生成委托实例需要两个参数:目标对象和要调用的方法的指针
callvirtinstance void ILTest.Computer::add_onAction( class [ESBasic]ESBasic.CbSimple)
ret
}
.method public hidebysiginstance void HandleAction()cilmanaged
{
ldarg. 0
dup
ldfldint32ILTest.ComputerManager::handleCount
ldc.i4. 1
add
stfldint32ILTest.ComputerManager::handleCount
ret
}
.method public hidebysiginstanceint32GetHandleCount()cilmanaged
{
ldarg. 0
ldfldint32ILTest.ComputerManager::handleCount
ret
}
}
}
最后,我们写个Main方法来测试一下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
.
namespace
ILTest
{
. class private autoansibeforefieldinitMainClass
{
.method public hidebysig static void Main( string []args)cilmanaged
{
.entrypoint
.localsinit
(
[ 0 ] class [ILTest]ILTest.Computercomputer,
[ 1 ] class [ILTest]ILTest.ComputerManagercomputerManager,
[ 2 ]int32count
)
newobjinstance void [ILTest]ILTest.Computer::.ctor()
stloc. 0
ldloc. 0
newobjinstance void [ILTest]ILTest.ComputerManager::.ctor( class [ILTest]ILTest.Computer)
stloc. 1
ldloc. 0
dup
dup
callinstance void [ILTest]ILTest.Computer::Increase()
callinstancevoid [ILTest]ILTest.Computer::Increase()
callinstancevoid [ILTest]ILTest.Computer::Increase()
ldloc. 1
callinstanceint32[ILTest]ILTest.ComputerManager::GetHandleCount()
stloc. 2
ldloca.s 2
callinstance string [mscorlib]System.Int32::ToString()
call void [mscorlib]System.Console::WriteLine( string )
call string [mscorlib]System.Console::ReadLine()
pop
ret
}
}
}
{
. class private autoansibeforefieldinitMainClass
{
.method public hidebysig static void Main( string []args)cilmanaged
{
.entrypoint
.localsinit
(
[ 0 ] class [ILTest]ILTest.Computercomputer,
[ 1 ] class [ILTest]ILTest.ComputerManagercomputerManager,
[ 2 ]int32count
)
newobjinstance void [ILTest]ILTest.Computer::.ctor()
stloc. 0
ldloc. 0
newobjinstance void [ILTest]ILTest.ComputerManager::.ctor( class [ILTest]ILTest.Computer)
stloc. 1
ldloc. 0
dup
dup
callinstance void [ILTest]ILTest.Computer::Increase()
callinstancevoid [ILTest]ILTest.Computer::Increase()
callinstancevoid [ILTest]ILTest.Computer::Increase()
ldloc. 1
callinstanceint32[ILTest]ILTest.ComputerManager::GetHandleCount()
stloc. 2
ldloca.s 2
callinstance 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的代码提示),截图如下: