C#——委托

什么是委托

  • 委托可以理解为指针
  • 一切皆皆地址
    变量(数据)是以某个地址为起点的一段内存中所存储的值
    函数(算法)是以某个地址为起点的一段内存中所存储的一组机器语言指令
  • 直接调用与间接调用
    直接调用:通过函数名来调用函数,cpu通过函数名直接获得函数所在地址并开始执行→返回
    间接调用:通过函数指针来调用函数,cpu通过读取函数指针存储的值获得函数所在地址并开始执行→返回
  • 委托的简单使用
    Action委托——不需要返回值
    Func委托——需要返回值
Class Program
{
    static void Main(string[] args)
    {
        func<int, int, int> func1 = new Func<int, int, int>(Add);
        Action action = new action(Printf);
        fun(1, 2);
        action();
    }
    int Add(int x, int y)
    {
        return x + y;
    }
    void Printf()
    {
        Console.WriteLine("我想委托");
    }

}

委托的声明(自定义委托)

  • 委托是一种类,类是数据类型所以委托也是一种数据类型
  • 他的声明方式与一般的类不同,主要是为了照顾可读性和C/C++的传统
  • 注意声明委托的位置——与类的声明平级
    避免写错地方结果声明成嵌套类型
  • 委托所封装的方法必须“类型兼顾”
    形参的数据类型与方法的返回值相同
Class delegate int Abc(int a, int b);
Class Program
{
    static void Main(string[] args)
    {
        Calc calc = new Calc();
        Abc abc1 = new Abc(calc.Add);
        Abc abc2 = new Abc(cal.Sub);

        Console.WritrLine(abc1(1, 2));
        Console.WriteLine(abc2(2, 1));
    }
}
Class Calc
{
    public int Add(int x, int y)
    {
        return x+ y;
    }
    public int Sub(int x, int y)
    {
        return x - y;
    }
}

委托的使用

  • 常规用法
  1. 模板方法(Function)
    一个完整的逻辑中间需要一个外部控制并返回一个参数,可以使用委托来补充,完善逻辑
  2. 回调方法(Action)
    需要回调其他的方法获得反馈
  • 缺点
  1. 可读性下降, debug难度增加
  2. 把委托回调,异步调用和多线程纠缠在一起,会让代码变得难以阅读和维护
  3. 委托使用不当有可能造成内存泄露和程序性能下降

委托的高级使用

  • 多播委托
    声明多个委托,合并委托,调用委托,多个委托自动一次执行
    eg:
func1 += func2;
func1 += func3;
func1();
  • 隐式异步调用
  1. 同步与异步
    同步:等待其他做完接着做
    异步:同时进行
  2. 同步调用与异步调用的对比
    每个运行的程序是一个进程
    每个进程可以有一个或者多个线程
    同步调用是在同一线程内
    异步调用的机理是多线程
    串行 = 同步 = 单线程,并行 = 异步 = 多线程
  3. 隐式多线程与显示多线程的对比
    直接同步调用:使用方法名
    间接同步调用:使用单播/多播的Invoke方法(使用委托)
    隐式异步调用:使用委托的BeginInvoke
func1.BeginInvoke(null, null)
func2.BeginInvoke(null, null)

//开启多线程, 两个委托同时进行
//第一个参数 说明委托结束后需要进行的操作

显式异步调用:使用Thread或Task

using Threading

Thread thread1 = new Thread(new ThreadStart(Printf1));
Thread thread2 = new Thread(new ThreadStart(Printf2));

thread1.start();
thread2.start();

void Printf1(){}
void Printf2(){}

//引用 Threading 类库
//创建 thread 对象并声明需要开线程的方法
//使用start方法开始线程

using Threading.Tasks
Task task1 = new Task(new Action(Printf1));
Task task2 = new Task(new Action(Printf2));

task1.start();
task2.start();

void Printf1(){}
void Printf2(){}
  • 应该适时使用接口取代一些对委托的使用
    接口可以完全替代委托
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值