经常会问事件是委托吗?
贸然的回答:是特殊的委托是有问题的.
首先看什么是委托:
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可以看到。不再粘出。