C# 委托(Delegate)(自定义委托+系统委托)+委托实例化与调用(五种绑定+调用方式+数组高阶函数)
2026/6/10 4:03:39 网站建设 项目流程

一、委托核心定义(必背原话)

委托(delegate)是一种存储函数的引用类型

委托的作用:用来匹配、存储、传递方法

核心规则:定义委托时,必须和目标方法的返回值、参数列表、参数个数、参数类型完全一致。

通俗理解:委托就是方法的载体,可以把方法当做参数传递


二、自定义委托语法(两种常用格式)

1. 无参数、无返回值委托

//定义一个不带参数、无返回值的委托类型 public delegate void MyDel1();

匹配规则:只能接收void 无参的方法。

2. 带参数、带返回值委托

//定义带2个int参数、int返回值的委托类型 public delegate int MyDel2(int a, int b);

匹配规则:只能接收返回值int、两个int参数的方法。


三、对应被传递的方法(委托适配方法)

//匹配 MyDel1(无参无返回) static void test() { Console.WriteLine("test"); } //匹配系统Func<int,int>(一个int参数、int返回值) static int test2(int a) { Console.WriteLine("test2"); return 10; } //匹配 MyDel2(两个int参数、int返回值) static int test3(int a,int b) { return 10; }

四、核心用法:委托作为方法参数(回调机制)

最高频用法:将委托类型作为方法参数,实现【方法传递、方法回调】

1. 自定义委托 MyDel1 作为参数

public static void F1(MyDel1 func) { func(); //执行传递进来的方法 Console.WriteLine("F1"); }

解析:

参数func是一个委托变量,可以接收匹配的方法

func()回调执行外部传进来的方法

2. 自定义委托 MyDel2 作为参数

public static void F3(MyDel2 f) { Console.WriteLine("F3"); }

解析:接收双参、int返回值的方法,代码内可随时回调执行。

3. 系统内置委托 Func

//Func<参数类型,返回值类型> public static void F2(Func<int,int> func) { func(10); //回调执行传入的方法 Console.WriteLine("F2"); }

知识点:

Func 是系统自带的有返回值委托

最后一个泛型参数 =返回值类型

前面泛型参数 =方法参数类型

Func<int,int>:代表【一个int参数、int返回值】的方法


五、Main 方法调用全程解析(执行顺序)

static void Main(string[] args) { Test.F1(test); Test.F2(test2); Test.F3(test3); }

逐行执行流程

1. Test.F1(test)

把 test 方法传入 F1 → F1 内部执行 func() → 输出 test → 输出 F1

执行顺序:test方法 ==> F1

2. Test.F2(test2)

把 test2 方法传入 F2 → F2 内部执行 func(10) → 执行test2 → 输出 F2

执行顺序:test2方法 ==> F2

3. Test.F3(test3)

把 test3 方法传入 F3 → F3 直接输出 F3(未手动回调,test3不执行)


六、完整输出结果

test F1 test2 F2 F3

七、自定义委托 VS 系统委托(必考)

1. 自定义 delegate

需要自己手动定义委托类型,灵活、适配任意场景

2. 系统内置委托

  • Func:有返回值的方法委托

  • Action:无返回值的方法委托


八、委托核心总结(简答题满分)

1. 委托是引用类型,专门用来存储、传递方法。

2. 委托定义必须和目标方法返回值、参数列表完全一致

3. 委托最大作用:将方法作为参数传递,实现回调、解耦代码

4. 自定义 delegate 灵活,系统 Func/Action 无需重复定义,开发更常用。


九、易错点总结

1. 参数不匹配、返回值不匹配 → 委托赋值报错

2. 委托参数方法,不调用 func() 就不会执行传入的方法

3. Func 最后一个泛型永远是返回值类型

委托实例化与调用(五种绑定+调用方式+数组高阶函数)

一、委托核心五要素(代码总结 必背)

1. 委托是引用类型

2. 专门用来存储/绑定方法

3. 可以通过实例化委托绑定匹配的方法;

4. 可以通过委托变量间接调用方法

5. 可作为方法参数,实现回调函数机制。


二、自定义委托定义

//无返回值、int+string双参数委托 public delegate void MyDel1(int a, string b); //有返回值、两个int参数委托 public delegate int MyDel2(int a, int b);

核心规则:委托签名必须和绑定方法的【返回值、参数个数、参数类型】完全一致。


三、被绑定的目标方法

1. 静态方法(Program类)

public static void F1(int a, string b) { Console.WriteLine($"F1方法a的值为:{a},b的值为:{b}"); } public static void F2(int a, string b) { Console.WriteLine($"F2方法a的值为:{a},b的值为:{b}"); }

2. 实例方法(Test类)

class Test { public int Add(int a ,int b) { return a + b; } }

四、委托四种绑定方式(重点必考)

方式1:完整实例化绑定(标准写法)

MyDel1 m1 = new MyDel1(F1); //调用 m1(10, "aaa");

通过new 委托类型(方法名)显式实例化,最规范、底层标准写法。

方式2:语法糖简写绑定(最常用)

MyDel1 m2 = F2; m2(10, "bbb");

编译器自动推断,省略 new,直接赋值方法名。

方式3:绑定【实例方法】(必须 new 对象)

MyDel2 m3 = new MyDel2(new Test().Add); Console.WriteLine(m3(10, 20));

非静态方法属于对象,必须通过对象.方法名绑定。

方式4:实例方法简写绑定

MyDel2 m4 = new Test().Add; Console.WriteLine(m4(30, 40));

五、委托两种调用方式

1. 简写调用(直接括号调用)

m4(30, 40);

2. 官方原生调用 Invoke()

m4.Invoke(10, 20);

本质:委托变量() 是 Invoke() 的语法糖,底层都是执行 Invoke。


六、委托空安全调用(面试高频)

MyDel2 m5 = null; //传统判断 if (m5 != null) { m5(10, 99); } //极简写法:空条件运算符 ?. m5?.Invoke(10, 20);

原理

如果委托变量为 null,不执行调用;

如果不为 null,自动执行 Invoke 调用方法。

开发强制规范:所有委托调用必须做空判断,防止空指针报错


七、直接调用 VS 委托间接调用区别

//1. 直接调用 F1(10, "sss"); new Test().Add(56, 90); //2. 委托间接调用 m1(10, "aaa"); m4(30, 40);

直接调用:写死方法,无法灵活替换

委托调用:方法可动态替换、可当参数传递、实现解耦和回调


八、数组高阶函数拓展(Lambda+委托应用)

所有 Array 高阶函数,本质都是接收委托参数,Lambda 是委托的简写形式。

int[] arr = { 1, 2, 3 }; Array.Find(arr, v => v % 2 == 0); //查找第一个匹配元素 Array.FindIndex(arr, v => v % 2 == 0); //查找第一个匹配下标 Array.FindAll(arr, v => v % 2 == 0); //查找所有匹配元素 Array.TrueForAll(arr, v => v % 2 == 0); //判断是否全部满足条件 Array.Exists(arr, v => v % 2 == 0); //判断是否存在满足条件 Array.ForEach(arr, v => Console.WriteLine(v)); //遍历所有元素

九、终极总结(简答题满分)

1. 委托是什么?

委托是一种引用类型,用于存储、绑定、传递方法,可以间接调用方法,常用于回调函数。

2. 绑定静态方法 vs 实例方法区别?

静态方法:直接 委托变量 = 方法名

实例方法:必须 通过对象.方法名 进行绑定

3. 委托安全调用规范?

使用委托?.Invoke()做空判断,避免空引用异常。

4. Invoke作用?

执行委托中绑定的方法,是委托调用的本质方法。


十、背诵口诀

委托引用存方法,签名一致才能绑

静态直接写方法,实例需要对象找

括号调用是简写,Invoke是原生宝

空判断不能少,问号Invoke最稳妥

C# 委托绑定与调用 核心易错点清单(考试/面试/开发避坑)

一、委托绑定 5 大易错点

1. 签名不匹配报错(最高频)

错误现象:绑定方法与委托的返回值、参数个数、参数类型不一致,直接编译报错。

易错场景:委托是双参数,绑定单参数方法;委托有返回值,绑定void方法。

正确规则:委托与目标方法返回值、参数数量、参数类型、参数顺序必须完全一致。

2. 绑定实例方法 忘记实例化对象

错误写法:直接绑定非静态方法MyDel2 m = Test.Add;

报错原因:实例方法属于对象,不属于类,不能直接通过类名访问。

正确写法MyDel2 m = new Test().Add;

3. 混淆静态方法与实例方法绑定规则

静态方法:无需实例对象,直接赋值方法名即可绑定。

实例方法:必须依托具体对象,否则无法绑定、编译失败。

4. 委托重复赋值 覆盖之前绑定的方法

易错认知:普通赋值 = 会覆盖原有方法,不会累加。

区分:单播委托用 = 覆盖;多播委托用 += 叠加绑定多个方法。

5. 委托初始为null 直接调用报错

高危报错:未绑定任何方法的委托变量默认是null,直接m()m.Invoke()报空引用异常。

规避方案:必须做空判断,优先使用m?.Invoke()极简安全写法。


二、委托调用 4 大易错点

1. 混淆直接调用与委托间接调用

直接调用:写死方法名,无法灵活替换,无复用性。

委托调用:通过委托变量间接执行,支持动态替换方法、回调传参,核心优势是解耦。

2. 忘记委托调用本质是 Invoke()

易错点:认为m(参数)是独立语法。

真相:括号调用是语法糖,底层本质都是执行Invoke()方法。

3. 调用参数数量/类型不匹配

绑定成功不代表调用正确,调用时传入参数和委托定义参数不一致,会直接编译报错。

例:委托定义双int参数,调用只传一个参数,语法报错。

4. 多播委托调用异常难以排查

多个方法绑定同一个委托,只要其中一个方法报错,整体调用直接终止,新手极易忽略。


三、语法简写易错点(高频坑)

1. 委托实例化简写乱用

标准写法:MyDel m = new MyDel(方法名);

简写写法:MyDel m = 方法名;

易错点:新手只记简写,不懂底层实例化原理,遇到复杂委托场景报错不会排查。

2. 混淆系统委托与自定义委托

Func:有返回值,最后一个泛型是返回值类型(极易写反参数和返回值)。

Action:无返回值,只传参数类型。

自定义delegate:完全自定义签名,不受系统委托限制。


四、考试/面试高频错题总结

  • 委托可以绑定任意方法(❌错,必须签名完全一致)

  • 实例方法可以直接通过类名绑定委托(❌错,必须new对象)

  • 委托变量可以直接调用,无需判空(❌错,会空指针报错)

  • m() 和 m.Invoke() 是完全不同的方法(❌错,语法糖与原生关系)

  • 单播委托赋值可以叠加多个方法(❌错,必须用+=多播)


五、终极避坑口诀

绑定先看签名对,实例必须对象配

默认null值别忘记,调用必做空判断位

单等覆盖多等加,Invoke才是原生类

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询