C#委托复习+委托与事件复习

委托复习

复制代码
namespace _1委托复习
{
    internal class Program
    {
        //1定义委托类型
        public delegate int MyDelegate(int a, string b);
        static void Main(string[] args)
        {
            //2 委托实例化
            //第一种实例化 通过new 进行实例化 参数是匹配函数
            MyDelegate m1 = new MyDelegate(F1);

            //4 委托间接调用函数
            F1(10, "11");//直接调用
            m1(10,"11");
            m1.Invoke(10, "11"); //通过invoke调用
            m1?.Invoke(10, "11");

            Console.WriteLine("--------------------");
            // //第二种种实例 直接赋值一个函数
            // m1 = F2;
            m1 += F2; //委托多播 
            m1(1, "ss");

            Console.WriteLine("--------------------");
            //第三种实例 lambda表达式实例
            m1 += (a, b) =>
            {
                Console.WriteLine("lambda表达式");
                return 10; //绑定一个lambda
            };
            m1(1, "ss");

            // 第四种实例 匿名委托
            m1 +=  delegate (int a, string b)
            {
                Console.WriteLine(" 匿名委托");
                return 10; //绑定一个lambda
            };
            m1(1, "ss");
         

        }
        //3 定义一个与委托类型匹配的函数
        public static int F1(int a,string b)
        {
            Console.WriteLine("F1函数");
            return 10;
        }
        public static int F2(int a, string b)
        {
            Console.WriteLine("F2函数");
            return 10;
        }
    }
}

委托与事件复习

一、事件与委托核心关系(必考)

1. 委托是什么?

委托是方法的容器、方法的类型、方法指针

可以存储多个方法、批量执行方法,是事件的底层基础。

2. 事件是什么?

事件是委托的安全封装

事件本质:private 的委托,对外只允许 +=、-=

事件不能直接赋值、不能在外部触发,更安全,专门用于 订阅/通知 机制

3. 一句话总结关系

委托是底层数据类型,事件是委托的特殊实例(只读、安全)

有委托不一定是事件,有事件一定有委托


二、自定义事件三大核心要素(背诵)

1、定义委托(规范方法签名)

规定:事件触发时,回调方法的 参数、返回值 格式

2、定义事件(public event 委托名 事件名)

对外公开,允许外部 订阅 +=

3、事件触发方法(内部调用)

判断事件是否为空,不为空则执行所有订阅的方法

事件只能在当前类内部触发,外部不能触发


三、事件运行机制(超级重点)

1、派发者(发布者)

自定义控件 MyButton

包含:委托、事件、触发方法

2、订阅者(观察者)

Form1、Program

通过 事件 += 方法 订阅

3、触发流程

鼠标点击按钮 → 触发系统Click → 执行内部触发方法 → 执行所有订阅的外部方法

系统事件驱动自定义事件


四、完整分层代码详解(原版全套整合)

1. 第一步:自定义委托(统一事件签名)

复制代码
// 自定义委托:匹配系统事件格式 (object sender, EventArgs e)
public delegate void MyEventHandle(object o, EventArgs e);

2. 第二步:事件发布类(自定义按钮 MyButton)【核心派发类】

该类负责:定义事件 + 触发事件

复制代码
internal class MyButton : Button
{
    // 1. 定义自定义事件(基于上面的委托)
    public event MyEventHandle MyClick;

    // 2. 事件触发方法(私有逻辑,内部触发)
    public void myButton_Click(object sender, EventArgs e)
    {
        // 判断是否有订阅者
        if (MyClick != null)
        {
            // 执行所有订阅的方法
            MyClick(null, null);
        }
    }
}

原理解析

MyClick 是事件,外部只能 += 订阅

触发只能由本类的 myButton_Click 执行

3. 第三步:窗体订阅事件(Form1 订阅者)

复制代码
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // 1. 系统原生按钮事件订阅
        button1.Click += button1_Click;

        // 2. 订阅【自定义事件】MyClick
        myButton1.MyClick += MyButton1_MyClick;

        // 3. 将系统Click绑定到自定义触发方法
        // 点击按钮 → 触发myButton_Click → 触发MyClick事件
        myButton1.Click += myButton1.myButton_Click;
    }

    // 系统按钮回调
    private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("内置Button");
    }

    // 自定义按钮事件回调
    private void MyButton1_MyClick(object o, EventArgs e)
    {
        MessageBox.Show("MyButton");
    }
}

4. 第四步:静态事件、系统内置事件演示(Program)

复制代码
internal static class Program
{
    // 系统自带事件类型
    public static event EventHandler MyEvent;

    // 自定义无参委托
    public delegate void MyDelete();

    // 自定义无参事件
    public static event MyDelete my;

    [STAThread]
    static void Main()
    {
        // 订阅系统事件
        MyEvent += (a, b) => { Console.WriteLine("内置的事件"); };
        // 手动触发
        MyEvent(null, null);

        // 订阅自定义无参事件
        my += Program_my;
        // 触发
        my();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    private static void Program_my()
    {
        Console.WriteLine("Program_my");
    }
}

五、完整执行流程(必考流程图解)

自定义按钮点击完整流程

1、用户点击 myButton1

2、触发系统原生 Click 事件

3、执行绑定的 myButton1.myButton_Click()

4、内部判断 MyClick 事件不为空

5、触发 MyClick 事件

6、执行订阅的 MyButton1_MyClick 方法

7、弹出 MessageBox.Show("MyButton")


六、委托 VS 事件 终极区别(考试简答题)

委托(delegate)

1、是一种数据类型

2、外部可以赋值、清空、调用

3、不安全

事件(event)

1、是委托的封装实例

2、外部只能 +=、-= 订阅取消

3、只能在本类内部触发

4、安全、符合观察者模式


七、代码结构总结(背诵)

1. 定义委托:规范方法签名

2. 定义事件:public event 委托 事件名

3. 编写触发方法:判断非空、Invoke执行

4. 外部订阅:事件 += 方法

5. 触发后自动执行所有订阅方法


八、易错点总结

1、事件只能在本类触发,外部不能直接调用

2、事件外部只能加减,不能赋值 =

3、委托可以随便赋值,不安全

4、自定义事件必须先判断非空再执行

5、系统 Click 是触发入口,自定义事件是业务逻辑


九、纯完整版可运行代码

Form1

program

Mybutton