委托复习
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

