C#中的委托与事件详解<个人总结>

委托的三种定义方法

  • new(典型方法)
  • 匿名类
  • lamda表达式
    事实上,这些方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        delegate void TestDelegate(string s);//注意这里!!这不是声明了一个变量,而是声明了一种类型!!!

        static void M(string  a) {
            Console.WriteLine(a);
        }
        static void Main(string[] args)
        {
            //C# 1.0
            TestDelegate delA = new TestDelegate(M);

            //C# 2.0
            TestDelegate delB = delegate(string s) { Console.WriteLine(s); };
            TestDelegate delBB=M;//可以直接用函数名来赋值
            //C# 3.0
            TestDelegate delC=(x)=>{Console.WriteLine(x);};//这种方式可以完全取代delB的那种方法。
            delA("TestDelegate delA");
            delB("TestDelegage delB");
            delC("TestDelegate delC");
            Console.ReadLine();
        }
    }
}

这个委托是不是看起来和函数指针很相像呢?

但是,稍微有点不同的是,一个委托可以指向多个函数!

//C# 1.0
            TestDelegate delA = new TestDelegate(M);
            delA += delegate(string s) { Console.WriteLine(s); };

+=可以在原来的委托上增加一个函数。
也就是说其实delegate 并不是一个典型的指针,而是一个链表,每一个节点拥有一个指针

还有一点,两个委托也可以进行运算

delA-=delB;

当然,以上只是比较简单的委托用法,我们看到了可以使用构造函数,可以用delegate(argv){}这样的匿名类,也可以直接(=M)这样简洁的赋值方式,最后还有(x)=>{}
如果你觉得这样的方法太多,那么就应该记住(=M)和(x)=>{}这两种(分别处理了不匿名和匿名方法)
另外,我们还了解到,一个委托变量和函数指针不同,它实际上是以多个函数指针构成的链表,这为我们多播(向多个类通知),实现了基础。

强烈建议先读懂上面,然后再开始时间!

观察者模式

让我们读一下下面这段程序

事件

其实是一种特殊的委托,定义一个时间其实相当于定义了一个委托+二个方法(编译器搞定的)
使用IL可以看到这两个方法,如果我们这样定义定义

event TestDelegate delA=M;

可是当我们将这行代码敲入VS之后,我们会发现,报错了!这是怎么回事?
注意,事件只能定义在类的内部。当我们使用static void Main()中定义时自然会报错。这是和之前所看到的委托的不同点。

话说回来,事件和委托的区别是,事件实现了订阅和发布的封装。这样大大提高了封装的可靠性,可以有效降低委托的误操作。

。。。待续

版权声明:本文为博主原创文章,转载请标明出处。

posted @ 2015-09-22 15:22  Fridge  阅读(153)  评论(0编辑  收藏  举报