C#委托的个人理解和体悟

委托是什么

  • 委托这个名称其实想表达的意思是,把一些数据委托给某个方法,从而实现某种目的。
  • 刚开始的时候,我也觉得委托这个东西好奇怪,明明直接调用对应的方法就可以了,为什么非要搞出这种难以理解的东西。
  • 直到开发的项目越来越复杂时,才有了一些自己的体悟。

示例

  • 先看一看委托的基本使用方法
csharp 复制代码
using System;

namespace demo02
{
    // 1. 声明委托类型
    // 委托是一种类,也可以定义在类中
    public delegate double Cal(double x, double y);
    class Program
    {
        // 3. 实例化委托方法
        static double CalMax(double x, double y) {
            return x > y ? x : y;
        }
        static double CalMin(double x, double y) {
            return x < y ? x : y;
        }
        static void Main(string[] args)
        {
            // 2. 实例化委托
            // 实例化的时候一定要提供具体方法(即委托做什么)
            Cal cal = new Cal(CalMax);
            // 写成Cal cal = CalMax; 也可以
            // 4.调用委托
            double result = cal(9, 12);
        }
    }
}
  • 当项目非常简单的时候,我们发现使用委托反而把代码弄得更加复杂,明明只要选择想要的方法,进行传参就可以完成相应的计算工作。
  • 可是,大家想象一下,如果今天开发的是一个大型项目,具体的算法由专门的算法部门进行编写,你只知道调用相关算法后,可以实现什么样的目的,而具体的计算过程你根本不知道,也根本不想知道时,你们如何能够实现跨部门的合作开发?
  • 首先,你们肯定要开对接会议,明确算法部门需要拿到哪些数据。我以数据库研发为例,假设我们今天需要对采集到的数据进行压缩,压缩算法由很多种,比如旋转门压缩、死区压缩等,我们需要做的事情就是,依据实际情况,选择一个最合适的压缩方法,完成压缩工作而已,具体的压缩方法是怎么写的,我们并不需要知道。
  • 对于方法的调用者来说,我们非常不希望写这个方法的人,提出一大堆稀奇古怪的参数要求,而对方同样也不希望我们一天到晚传一堆乱七八糟的参数进去,请求压缩,所以大家会事先商量好传参规范,也就是接口 ,在这里,委托的参数、返回值就起到了接口的作用,从而在跨团队的合作开发中,免去了很多不必要的麻烦。同时也极大地增加了程序算法的扩展性
  • 另外,从设计模式的角度进行考虑,我们总是希望尽可能少对代码进行改动。我们通常将业务模块和算法模块当成两个不同的部分,对于业务模块的相关开发者而言,如果想要更改一种算法,要做的仅仅是更改委托函数的名称,其余逻辑代码没有丝毫改变,极大保障了业务逻辑的稳定性。就算法模块而言,如果更改算法之后,程序出现了某些异常现象,只需对这一种算法进行优化调整,对程序的整体逻辑不会构成任何影响。

变式

  • 在实际开发过程中,我们比较喜欢以回调函数的形式,将函数名称作为参数进行传递,因此,我们一般将示例中的代码改写为如下形式:
csharp 复制代码
using System;

namespace demo02
{
    // 1. 声明委托类型
    // 委托是一种类,也可以定义在类中
    public delegate double Cal(double x, double y);
    class Program
    {
        // 3. 实例化委托方法
        static double CalMax(double x, double y) {
            return x > y ? x : y;
        }
        static double CalMin(double x, double y) {
            return x < y ? x : y;
        }
        // 将委托作为参数进行传递
        static double Test(Cal f, double x, double y) {
            return f(x, y);
        }
        static void Main(string[] args)
        {
            // 2. 实例化委托
            Cal cal = CalMax;
            // 4.调用委托
            double result = Test(cal, 9, 12);
        }
    }
}
  • 使用委托时,我们发现调用的方法是一个变量,当代码复杂时,函数的写法类似于:
csharp 复制代码
// 逻辑判断代码
if (...) {
	Cal cal = CalMax;
} else if (...) {
	Cal cal = CalMin;
}
// 接后续业务代码
var result = Test(cal, a, b);
  • 从而可以将逻辑判断部分的代码和业务代码完全分离开。

委托的风险

  • 假设我们今天写了两个委托,即:delegate 1 和 delegate 2。一旦我们将delegate 1 = delegate 2,那么delegate 1 容器内存在的数个函数将会直接被清空。
相关推荐
zzzhpzhpzzz3 分钟前
Win10快速安装.NET3.5
.net·win10
许泽宇的技术分享2 小时前
Windows MCP.Net:基于.NET的Windows桌面自动化MCP服务器深度解析
windows·自动化·.net
一枚小小程序员哈3 小时前
基于微信小程序的家教服务平台的设计与实现/基于asp.net/c#的家教服务平台/基于asp.net/c#的家教管理系统
后端·c#·asp.net
Eternity_GQM5 小时前
【Word VBA Zotero 引用宏错误分析与改正指南】【解决[21–23]参考文献格式插入超链接问题】
开发语言·c#·word
cimeo9 小时前
【C 学习】06-算法&程序设计举例
c#
百锦再10 小时前
.NET 的 WebApi 项目必要可配置项都有哪些?
java·开发语言·c#·.net·core·net
WYH28720 小时前
C#控制台输入(Read()、ReadKey()和ReadLine())
开发语言·c#
hqwest21 小时前
C#WPF实战出真汁06--【系统设置】--餐桌类型设置
c#·.net·wpf·布局·分页·命令·viewmodel
做一位快乐的码农1 天前
基于.net、C#、asp.net、vs的保护大自然网站的设计与实现
c#·asp.net·.net
DavieLau1 天前
C#项目WCF接口暴露调用及SOAP接口请求测试(Python版)
xml·服务器·开发语言·python·c#