c# 常见委托有 delegate,Action,Func,Predicate。那它们有什么区别和联系呢?
1. Func , Action , Predicate 区别
定义
查看源码可以发现:
Action , Func , Predicate 都是系统使用 delegate 定义的泛型委托。
它们具有不同的参数和返回值。
使用 in,out 定义了逆变和协变。
public delegate void Action<in T>(T obj);
public delegate TResult Func<in T, out TResult>(T arg);
public delegate bool Predicate<in T>(T obj);
根据源码可以判断:
我们可以使用 delegate 代替 Action , Func , Predicate 这三种委托。
我们也可以使用类似的方法定义自己的委托。
根据委托的名字也可以判断大致的使用场景:
Action 代表动作,代表执行一项操作,所以不具有返回值。
Func 代表普通的函数,有参数和返回值。
Predicate 断言,常用于判断数据是否符合要求。
参数和返回值区别:
-
Func 至少 0 个参数,至多 16 个参数,必须有返回值,不能为 void 。
public int Test<T1,T2>(Func<T1,T2,int>func,T1 a,T2 b) { return func(a, b); } -
Action 至少 0 个参数,至多 16 个参数,无返回值。
public void Test<T>(Action<T> action,T p) { action(p); } -
Predicate 有且只有一个参数,返回值必须为 bool 。
public bool Test<T>(Predicate<T> predicate,T p) { return predicate(p); }
2. delegate、Delegate、MulticastDelegate区别
委托继承的层次关系
System.Object
=> System.Delegate
==> System.MulticastDelegate
===> 使用 delegate 关键字自定义的委托
继承层次来源
前 3 层(Object,Delegate,MultiDelegate)来源于文档。 delegate继承是根据代码编译后生成的中间语言得出。
使用 ildasm.exe 可以看到,编译器将
delegate编译为继承MulticastDelegate的类
public delegate void BinaryOp(int x);
区别
Delegate
Delegate 是一个委托的基类。定义了一些委托的基础方法。
MulticastDelegate
MulticastDelegate 继承Delegate ,并对其进行了一些扩展。
delegate
我们不能直接继承 Delegate 和 MulticastDelegate。只有系统和编译器可以继承它们。
我们需要使用 delegate 关键字来定义委托,编译器会自动将委托编译为一个继承 MulticastDelegate 的类,并添加 BeginInvoke,EndInvoke,Invoke 等方法。例如上图图1。
总结
Action,Func,Predicate都是系统使用delegate定义的委托。使用
delegate定义的委托 其实是继承MulticastDelegate的类(这也是为什么使用委托要先new的原因:BinaryOp a = new BinaryOp(o=>{});)。
本文讲解的几种常用委托的区别。如有错误或遗漏之处,请在评论中指出。谢谢。
参考文章:
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。