C#委托+事件

1.委托:相当于函数指针,本质上是一个类,可以实例化,类内部存在指向方法的字段属性。
至于为什么使用委托,我个人认为它提高了程序的扩展性,在程序更新的时候,不需要大幅度修改程序内部的主要逻辑,只需要在原有的基础上进行扩展。

委托:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelegateTest
{
    internal class Program
    {
        //委托:将方法作为参数传递,而且方法的参数列表和返回值要与委托类型一致
        //无参无返回值的委托
        public delegate void DelegateTest();
        //有参无返回值的委托
        public delegate void DelegateTest2(int num,string str);
        //有参有返回值的委托
        public delegate int DelegateTest3(int num);
        static void Main(string[] args)
        {
            //DelegateTest dt = new DelegateTest(Test); //函数传递的一种方式
            DelegateTest dt = Test;//函数传递
            dt();
            DelegateTest2 dt2 = new DelegateTest2(Test2);
            dt2(80,"张三");
            DelegateTest3 dt3 = Test3;
            int num = dt3(101);
            Console.WriteLine(num);
        }
        public static void Test()
        {
            Console.WriteLine("DelegateTest");
        }
        public static void Test2(int num,string str)
        {
            Console.WriteLine($"{str}:{num}");
        }
        public static int Test3(int num)
        {
            Console.WriteLine(num);
            return num;
        }
    }
}

多播委托:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelegateTest
{
    internal class Program
    {
        //多播委托:可以合并或移除多个委托对象,多播委托被调用时,它所合并的方法组或方法列表都会被调用,而且只有相同类型的委托对象才能合并
        public delegate void DelegateTest();
        static void Main(string[] args)
        {
            DelegateTest dt = Test;//函数传递
            dt += Test2;//合并
            DelegateTest dt2 = Test3;
            dt += dt2;//合并
            dt();
            dt -= Test2;//移除
            dt();
        }
        public static void Test()
        {
            Console.WriteLine("Test");
        }
        public static void Test2()
        {
            Console.WriteLine("Test2");
        }
        public static void Test3()
        {
            Console.WriteLine("Test3");
        }
    }
}

匿名委托:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelegateTest
{
    internal class Program
    {
        delegate void DelegateTest();
        static void Main(string[] args)
        {
            //匿名委托
            DelegateTest dt = delegate () { Console.WriteLine("匿名委托"); };
            //Lambda表达式的写法
            DelegateTest dt2 = () => Console.WriteLine("Lambda");
            dt += Show;
            dt();
            dt += dt2;
            dt();
        }
        static void Show()
        {
            Console.WriteLine("Show");
        }
    }
}

2.事件:相当于保存委托的数组,它是基于委托的。事件是一种特殊的委托,通过事件可以注册、取消多个多个委托和方法。算是完成用户操作所需要的委托和方法的集合。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelegateTest
{
    internal class Program
    {
        public delegate void DelegateTest();
        //定义事件:事件是一个特殊的委托,事件可以作为变量拿到类之外去使用,但是发布必须在定义类里面实现
        public static event DelegateTest EventDT;
        static void Main(string[] args)
        {
            Student student = new Student();
            student.GetInfo();//驱动方法内的事件进行注册
            EventDT();//事件发布
        }
    }
    class Student
    {
        private string name;
        private int age;
        //访问器
        public string Name
        {
            set { name = value; }
            get { return name; }
        }
        public int Age
        {
            get => age; set => age = value;
        }
        public void ShowInfo()
        {
            Console.WriteLine("张三:18");
        }
        public void ShowInfo2()
        {
            Console.WriteLine("李四:19");
        }
        public void GetInfo()
        {
            Program.DelegateTest dt = ShowInfo2;
            Program.EventDT += ShowInfo;//注册方法
            Program.EventDT += dt;//注册委托
        }
    }
}

3.委托与事件的区别:

(1)委托在类内类外都可以声明。事件只能在类内声明。
(2)委托和事件都可以在类内类外注册和注销方法,但是事件只能在类内调用,而委托可以在类内类外调用,使用事件可以提高调用的安全性,防止事件的调用权限被别人随便使用
(3)委托特别用于实现事件和回调方法。C#中使用事件实现线程间的通信,就像一个对外的接口

参考:

https://www.runoob.com/csharp/csharp-delegate.html
https://www.runoob.com/csharp/csharp-event.html
https://blog.csdn.net/shanniuliqingming/article/details/119547799?spm=1001.2014.3001.5506

结语:合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。

猜你喜欢

转载自blog.csdn.net/falsedewuxin/article/details/129986807