首页 > 代码库 > C# 委托和事件(一):最简单的委托和事件

C# 委托和事件(一):最简单的委托和事件

 

C#的事件基于委托,所以先说委托。

一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手。所以我需要一个实际的场景。

明天刚好考试(商务英语),考试上有两个角色(class):老师(Teacher)和学生(Student),在考试时间终止的时候,老师会触发(invoke)一个事件(event):“考试时间到了,我tm要收卷子了!”(OnTestTimeUp),而每个学生都要订阅这个事件,并在这个事件发生的时候上交试卷(HandInTestPaper)。如果不用事件的话,老师在时间结束的时候就要调用每个学生的的HandInTestPaper方法,如果使用事件,只要在学生被实例化的时候在事件上增加一个订阅即可。

1、老师和学生之间的桥梁

老师和学生之间的桥梁用委托来完成,这里就用最简单的一种委托:没有返回、没有参数、不支持泛型:

public delegate void TestTimeUpHandler();

接着,用这个委托定义一个事件,这样学生就可以订阅这个事件

public event TestTimeUpHandler TestTimeUp;

学生订阅事件后,当老师触发这个事件的时候,学生就会做出一些响应

public void OnTestTimeUp()
{
    TestTimeUp?.Invoke();
}

2、学生如何订阅?

首先回到刚才的委托,这个委托非常简单,没有返回、没有参数,所以学生类中只要有一个方法,签名与这个一致就可以订阅这个事件:

public void HandInTestPaper()
{
    Console.WriteLine("The test paper has been handed in.");  
}

然后在实例化后直接将这个方法订阅给事件即可

3、两边的关系

技术分享

4、完整的例子

Delegate

    /// <summary>
    /// 委托,考试时间到的Handler
    /// </summary>
    public delegate void TestTimeUpHander();

Teacher

    /// <summary>
    /// 教师类
    /// </summary>
    public class Teacher
    {
        public event TestTimeUpHander TestTimeUp;

        public void OnTestTimeUp()
        {
            TestTimeUp?.Invoke();
        }
    }

Student

    /// <summary>
    /// 学生类
    /// </summary>
    public class Student
    {
        public string Name { get; private set; }

        public Student(string name)
        {
            this.Name = name;
        }

        public void HandInTestPaper()
        {
            Console.WriteLine($"{this.Name}\‘ paper has been handed in");
        }
    }

5、具体场景实现

    public class Program
    {
        public static void Main()
        {
            Teacher teacher = new Teacher();
            var tom = new Student("Tom");
            var jerry = new Student("Jerry");
            var spark = new Student("Spark");
            var tyke = new Student("Tyke");

            // 订阅teacher的TestTimeUp事件
            teacher.TestTimeUp += tom.HandInTestPaper;
            teacher.TestTimeUp += jerry.HandInTestPaper;

            // invoke TestTimeUp 事件
            teacher.OnTestTimeUp();

            Console.WriteLine();

            teacher.TestTimeUp -= tom.HandInTestPaper;
            teacher.TestTimeUp += tyke.HandInTestPaper;

       teacher.OnTestTimeUp(); Console.ReadKey(); } }

运行的结果如下:

技术分享

可以看到,第一次触发事件的时候,只有Tom和Jerry两个订阅了事件的实例执行了HandInTestPaper方法,第二次触发事件前,移除了Tom的订阅,同时增加了Tyke的订阅,所以Jerry和Tyke执行了HandInTestPaper方法。

以上,是最简单的C#委托与事件的实现,复杂的方法日后再说

 

C# 委托和事件(一):最简单的委托和事件