您的位置:首页 > 编程语言 > C#

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

2015-09-22 15:22 351 查看

委托的三种定义方法

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()中定义时自然会报错。这是和之前所看到的委托的不同点。

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

。。。待续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: