C# 中的委托机制(delegate、action、func)
前言
简单了解了 C# 中的 Delegate、Func、Event、Action。粗略理解:委托是一个规定了参数的函数待执行队列;Func 是只有一参一返的 Delegate;Action 是一参无返的 Delegate;Event 是?
主要参考了 C# 的委托与事件大致是怎么一回事_哔哩哔哩_bilibili,一个很好的视频。
委托 Delegate
委托的底层是一种函数指针。顾名思义委托的作用就是,当一个函数“不方便做某事”的时候,“拜托”另一个函数去做。可以用于实现事件与回调。
所有的委托都派生自 System. Delegate 类。
声明一个委托
委托的声明
1 | delegate <return type> <delegate-name> <parameter list> |
委托经过声明以后决定其可以引用的方法。方法与声明有相同的参数、返回类型、标签(关于标签参考此 CSDN 博客)。换句话说,委托的声明决定了它能调用什么样的方法,委托是被调用方法的模板。
实例化委托
声明完成后,可以用 new 实例化一个委托实例,并且在参数中指定实例调用的方法。如下
1 | public delegate void printString(string s); |
最后向委托中传递参数即可。如下是一个完整的例子(From:runnoob)
1 | using System; |
委托的多播
如果委托对象(即实例)的类型相同,则可以合并、分离委托(使用 +
和 -
运算符),这被称之为委托的多播或组播。如下是一个例子(From:runnoob)
1 | ... |
Func
Func 是委托的一种,它固定具有一个参数和一个返回值。
格式如下:
1 | Func <parameter_type,return_type> expression; |
Expression 可以是一个 lambda 表达式,也可以是一个方法。是方法的时候,这个方法和 Func 一样必须有一个传入值和一个返回值。这样,就可以把方法作为参数进行传递,同时不必像委托一样显式的进行定义声明。
Lambda 表达式的举例:
1 | Func<string, string> convert = s => s.ToUpper(); |
实例化委托方法的举例:
1 | Func<string, string> convertMethod = UppercaseString; |
Action
Action 也是委托的一种,它一定具有一个参数,并且没有返回值。
即: Action <T> name
总的来说,和 Func 差别不大。同样可以给它赋值为 lambda 表达式或方法。只要这个方法有一个参数并且没有返回值。
Event
Event 是一种特殊的委托,但是其复制的权限为 delegate。使用 Delegate 的时候,我们不一定想立刻为其赋值。这种情况下,我们可以考虑使用 Event。
事件的声明:
1 | delegate void MyDelegate(); |
事件声明完成后就是一个实例了(类似变量)。
当作为类成员的时候, event 只能在类中被调用。
Event 的一种用处:让类外成员可以观测到类的私有成员发生了变化。
在类中定义私有成员的 public {get; set;} 变量,set 时,invoke 类中的 event;
类外事物需要观测时,在 event 中注册函数就会收到通知。
参考
- C# 的委托与事件大致是怎么一回事_哔哩哔哩_bilibili
- C# 委托(Delegate) | 菜鸟教程
- Func<T,TResult> 委托 (System) | Microsoft Learn
- 三分钟彻底搞懂委托,事件,Action,Func的作用和区别_哔哩哔哩_bilibili
延申
- 逆变与协变类型请参考:Covariance and Contravariance in Generics | Microsoft Learn
- Lambda 表达式部分参考: