C#委托和事件详解

1. 委托?

A:委托字面意思就是一种代理
B:C#语言里面委托则是让某个方法来实现需求的功能
C:从数据结构方面来讲委托则是和类一样,是一种自定义类型
D:委托它是对方法一类的抽象,就是一系列具有相同签名和返回类型的方法的地址,也就是说它存储的是方法的地址而不是方法本身
F:调用委托的时候,委托一系列的方法都会按照顺序被执行

2. Demo?

比如我们定义一个人类Person如下,具有两个方法 打招呼用英语,打招呼用中文。
定义的委托参数必须传入一个string类型的姓名,无返回值 SayHelloByChinese和SayHelloByEnglish都符合委托的类型。

    public delegate void SayHelloDelegate(string name);
    public class Person
    {
        public SayHelloDelegate SayHello1;
        public void SayByChinese(string name)
        {
            Console.WriteLine(name + "你好");
        }
        public void SayByEnglish(string name)
        {
            Console.WriteLine(name + "HI");
        }
    }

```csharp
class Program
    {
        static void Main(string[] args)
        {
            Person person= new Person();
            person.SayHello = person.SayByChinese;
            person.SayHello += person.SayByEnglish;
            person.SayHello("强爸爸");
            person.SayHello("周爸爸");
            Console.ReadKey();
        }
    }

3. 事件?

事件就是对委托进行了封装,可以理解为一种特殊的委托
通过reflector反编译可以得知,当我们定义了事件的时候

public event SayHelloDelegate SayHelloEvent;

**编译器会自动给他一个private委托变量以及Add和Remove方法,这两个方法主要就是对委托变量进行增加委托和删减委托的操作。也就是说在这个类的外部,我们只能对他进行+=和-=的操作,这样也符合面向对象封装的原则,保证了内部变量的安全,当事件触发的时候,私有化变量委托就会执行。
划重点:那么问题来了?我觉得最重要的就是事件会只能在类的外部去注册和删减,至于具体的响应则是由类的内部决定的,这样就解决了以下我思考的问题。
第一:在我们设计的时候,并不是所有的东西都可以声明为public的,那么问题来了,如果没有事件,我们直接将委托delegate声明为private,那么它的意义何在?我们声明一个委托就是为了让其他地方去使用的,结果私有化了,使用的意义就不在了,注意这里的前提是没有事件的情况下。
第二:在我们设计的时候,如果声明为public那么客户端的操作就可能会造成破坏性,当我们在给一个委托=的时候,它是不会管之前有没有已经被委托的方法,而是直接覆盖,客户端操作不当会造成严重后果。
所以事件的出现正是对委托进行了一些限制,让它只能够从类的外部去进行注册和取消,而至于事件的响应则应该由类的内部来决定。下面代码作出解释:

public delegate void SayHelloDelegate(string name);
    public class Person
    {
        public event SayHelloDelegate SayHelloEvent;
        public SayHelloDelegate SayHello;
        public void SayByChinese(string name)
        {
            Console.WriteLine(name + "你好");
        }
        public void SayByEnglish(string name)
        {
            Console.WriteLine(name + "HI");
        }
        public void StartEvent()
        {
            if (SayHelloEvent !=null)
            {
                SayHelloEvent("强爸爸");
            }
        }
    }

**可以看到当我们在事件的外部进行响应的时候是不被允许的,而委托则可以。**

 static void Main(string[] args)
        {
            Person person = new Person();
            person.SayHelloEvent += person.SayByChinese;
            person.SayHelloEvent += person.SayByEnglish;
            person.StartEvent();
            //person.SayHello += person.SayByEnglish;
            //person.SayHello += person.SayByChinese;
            //person.SayHello("强爸爸");
            Console.ReadKey();  
        }

StartEvent()是在事件的内部的方法专门用来触发事件,也就是说在事件的触发完全是由事件的内部进行响应的。
综上所述:事件就是一种特殊的委托,对委托进行了封装,限制了委托的一些作用域。就好比面和面包一样,委托就是面,而面包则是用面做出来的。当我们需要油条的时候,则面包就不能发挥作用了,那个时候就需要用到原生的面粉了,也就是我们这里的委托。

原创文章 37 获赞 11 访问量 2729

猜你喜欢

转载自blog.csdn.net/qq_39691716/article/details/105743486
今日推荐