C# 事件是委托吗?

经常会问事件是委托吗?

贸然的回答:是特殊的委托是有问题的.

首先看什么是委托:

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可以看到。不再粘出。

猜你喜欢

转载自blog.csdn.net/qqqgg/article/details/80034474