经常会问事件是委托吗?
贸然的回答:是特殊的委托是有问题的.
首先看什么是委托:
internal static class Program
{
private delegate void de();
[STAThread]
private static void Main()
{
Console.WriteLine("*************############################################");
de d = Program.test;
d();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
对应的IL如下:可以看到IL中可没有什么delegate关键字啊。delegate会编译为一个密封类,
继承自System.MulticastDelegate。
.class private auto ansi abstract sealed beforefieldinit StringTest.Program
extends [mscorlib]System.Object
{
// Nested Types
.class nested private auto ansi sealed de
extends [mscorlib]System.MulticastDelegate
{
// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor (
object 'object',
native int 'method'
) runtime managed
{
} // end of method de::.ctor
.method public hidebysig newslot virtual
instance void Invoke () runtime managed
{
} // end of method de::Invoke
.method public hidebysig newslot virtual
instance class [mscorlib]System.IAsyncResult BeginInvoke (
class [mscorlib]System.AsyncCallback callback,
object 'object'
) runtime managed
{
} // end of method de::BeginInvoke
.method public hidebysig newslot virtual
instance void EndInvoke (
class [mscorlib]System.IAsyncResult result
) runtime managed
{
} // end of method de::EndInvoke
} // end of class de
// Methods
.method private hidebysig static
void Main () cil managed
{
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x210c
// Code size 57 (0x39)
.maxstack 2
.entrypoint
.locals init (
[0] class StringTest.Program/de
)
// sequence point: (line 16, col 9) to (line 16, col 10) in c:\users\administrator\source\repos\StringTest\StringTest\Program.cs
IL_0000: nop
// sequence point: (line 19, col 13) to (line 19, col 92) in c:\users\administrator\source\repos\StringTest\StringTest\Program.cs
IL_0001: ldstr "*************############################################"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
// sequence point: (line 20, col 13) to (line 20, col 25) in c:\users\administrator\source\repos\StringTest\StringTest\Program.cs
IL_000c: ldnull
IL_000d: ldftn void StringTest.Program::test()
IL_0013: newobj instance void StringTest.Program/de::.ctor(object, native int)
IL_0018: stloc.0
// sequence point: (line 21, col 13) to (line 21, col 17) in c:\users\administrator\source\repos\StringTest\StringTest\Program.cs
IL_0019: ldloc.0
IL_001a: callvirt instance void StringTest.Program/de::Invoke()
这样一看,初学者感到的委托莫名奇妙声明就可以简化了。
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
De d = test;
d();
A a = new A();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
delegate void De();
class A { }
static void test()
{}
事件是可以处触发执行的!是对象!所以事件是特殊委托的实例。
特殊在哪儿呢?私有而已!IL可以看到。不再粘出。