当前位置: 首页 > article >正文

C#中委托和函数类的关系

函数类并不完全等同于委托,但两者之间确实有密切关系。在 C# 中,委托是一个类型,用来封装具有特定参数和返回值的方法。你可以将委托理解为函数的“引用类型”或者“类”。委托允许你将方法作为参数传递给其他方法,并且可以动态地调用这些方法。


委托和函数类的关系

  1. 委托的定义和作用 委托是一种类型,用于引用方法。它定义了方法的签名(参数和返回类型)。

    示例:

    public delegate int MathOperation(int x, int y);
    

    这里,MathOperation 是一个委托类型,它可以引用任何接受两个 int 参数并返回 int 的方法。

    用法:

    MathOperation add = (a, b) => a + b; // 使用 Lambda 表达式
    Console.WriteLine(add(3, 5)); // 输出 8
    

    在这里,MathOperation 就像一个函数类,用来承载一个具体的方法实现。


  1. 内置的委托类型(函数类的简化版) 为了简化自定义委托的定义,C# 提供了一些常用的内置委托类型,可以理解为通用的函数类:

    • Func: 表示有返回值的方法。
    • Action: 表示没有返回值的方法。
    • Predicate: 表示返回布尔值的方法。

    示例:

    Func<int, int, int> add = (x, y) => x + y;  // 等价于自定义的 MathOperation 委托
    Action<string> print = message => Console.WriteLine(message); // 没有返回值的方法
    Predicate<int> isPositive = x => x > 0; // 返回布尔值的方法
    

  1. 委托 vs 类 虽然委托在语义上有“类”的一些特性,但它不是完全意义上的类。委托的主要功能是“引用方法”,它并不具有类的所有功能。

    • 委托的主要特点是封装和调用方法,而类则用于定义数据和行为。
    • 委托实例实际上是一种多播委托,可以包含多个方法,而类实例则是包含数据和方法的对象。

对比委托和类的核心区别

特性委托
定义目的用于引用方法用于定义数据和行为
是否包含数据不包含实例数据包含字段、属性和方法
实现的功能封装方法,并动态调用提供数据结构和行为的封装
内置支持的泛型有(FuncActionPredicate需要显式定义泛型类
运行时动态性动态绑定方法静态或动态绑定

委托的类特性

在底层,委托实际上是一个类。编译器在处理委托时,会为每个委托类型生成一个类。以下是关键特性:

  • 委托类可以存储方法列表(支持多播)。
  • 委托对象本质上是委托类的实例。

示例底层生成:

// C# 代码
public delegate int MathOperation(int x, int y);

// 编译器会生成类似如下的类
public class MathOperation : System.MulticastDelegate
{
    public MathOperation(object object, IntPtr method);
    public virtual int Invoke(int x, int y);
    public virtual IAsyncResult BeginInvoke(int x, int y, AsyncCallback callback, object @object);
    public virtual int EndInvoke(IAsyncResult result);
}

因此,从技术角度讲,委托可以被视为一个类,但它的功能更专注于方法的封装和调用。


总结

函数类 ≈ 委托,但并不完全相同。委托是用于封装方法的类型,它在编译时会生成一个类。你可以将委托理解为一种专门为函数设计的轻量级类。C# 的内置委托类型(如 FuncAction)大大简化了委托的使用,使其更接近于常见的函数式编程中的“函数类”概念。


http://www.kler.cn/a/506910.html

相关文章:

  • 移动端H5缓存问题
  • 【Vim Masterclass 笔记12】S06L26 + L27:Vim 文本的搜索、查找及替换同步练习(含点评课)
  • 一文掌握Docker
  • Spring Boot 下的Swagger 3.0 与 Swagger 2.0 的详细对比
  • 类模板的使用方法
  • ​​​​​​​​​​​​​​★3.3 事件处理
  • 11-2.Android 项目结构 - themes.xml 文件基础解读
  • 微信小程序web-view 外链白屏, 分享后白屏?
  • 解决关于Xcode16提交审核报错
  • 11-3.Android 项目结构 - 认识 .idea 目录
  • 如何在QT中保证线程是安全的?
  • 多包单仓库(monorepo)实现形式
  • 代码随想录算法【Day22】
  • 零基础入门uniapp Vue3组合式API版本
  • uniApp开通uniPush1.0个推,SpringBoot集成uniPush1.0个推
  • SDL2:PC端编译使用
  • dockerfile1.0
  • 【使用EasyExcel快速实现数据下载到Excel功能】
  • Vue进阶之Vue3后台系统
  • 【C#】WPF项目,项目目录文件解析、WinForms 和 WPF 的概念及其区别与联系
  • Spring boot面试题---- Spring boot项目运行原理
  • 基于Python SciPy的拥塞控制算法模拟
  • 【.net core】【sqlsugar】时间查询示例
  • tui-editor报错
  • 【数据结构练习题】栈与队列
  • ThreeJs功能演示——几何体操作导入导出