热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

委托与事件、匿名方法与Lambda表达式

委托:委托就是把方法或函数以变量的形式来使用。委托的使用步骤:定义方法Func()->定义委托类型->声明委托类型的变量->注册方法->调用1、

委托:

委托就是把方法或函数以变量的形式来使用。

委托的使用步骤:

定义方法Func() -> 定义委托类型 -> 声明委托类型的变量 -> 注册方法 -> 调用

1、定义方法
    pubic static void Func()
    {
        Consoe.Writeine("我是一个静态的无参无返回值的方法");
    }
2、委托类型(注意)
    -> 语法:
        pubic deegate 方法签名(参数规则);
        -> 拿到方法,删除返回类型前的所有东西与方法参数圆括号后的所有东西
            void Func()
        -> 在剩下的代码前加上[pubic] deegate
            pubic deegate void Func()
        -> 在最后加上分号
            pubic deegate void Func();
        -> 一般在方法名后加上Deegate
            pubic deegate void FuncDeegate();
3、使用,定义委托类型的变量
    -> 该委托的类型名为
        pubic deegate 返回类型 委托类型名(参数);
    -> 定义(一般委托变量用Pasca命名规则)
        FuncDeegate MyFunc;
4、直接将方法名赋值给委托变量
    MyFunc = Func;
    // 一旦完成赋值,就表示MyFunc与Func是同一个方法
    // 就好像"计算机"与"电脑"的关系一样,是一个方法的两个不同名字
5、调用
    方法原本怎么调用,委托变量就怎么调用
        原来:Func();
        现在:MyFunc();

    -> 补充说明
        -> 多个类中如何调用
            在cass MyCass中写一个方法,然后在Main方法中用委托调用
        -> 在定义中系统定义的委托多半以Hander结尾
        -> 委托变量赋值
            MyFunc = Func;
            MyFunc = new FuncDeegate(Func);
            // 委托的本质是一个"类"
        -> 委托的调用
            委托变量();
            委托变量.Invoke();


8、 补充——多态
    -> 实现的最基本的要求
        -> 继承
        -> 子类父类有完"全相同的方法"
            返回类型 方法名(参数)
        -> 父类要virtua或abstract,子类要override

9、 既然委托是类型,我们使用的实际是该类型的变量
    既然是变量就可以当做方法的参数进行传递和返回
    -> 写一个方法,传入一个整数,在方法中使用整数
        pubic static void Func(int num)
        {
            num *= 2;
            Consoe.Writeine(num);
        }
        传入:就在方法后的圆括号中写上对应类型的局部变量
        使用:就是在方法中按照指定规则使用就可以了
    -> 写一个方法,传入一个委托变量,并使用
        pubic void Func(FuncDeegate  aa)
        {
            aa();
        }

10、自定义排序
    -> 排序字符串
        -> 按照字符串的长度排序
        -> 按照字符串的字典排序
    -> 先按照一个规则写一个排序算法(冒泡)
        strs
        for(int i = 0; i         {
            for(int j = 0; j             {
                if(strs[j].ength > strs[j+1].ength)
                {
                    string temp = strs[j];
                    strs[j] = strs[j+1];
                    strs[j+1] = temp;
                }
            }
        }
    -> 思考第二种排序规则是什么,与第一种代码实现的区别是什么
        string.Compare(str1, str2)
        str1 > str2        1
             =            0
             <            -1
        if(string.Compare(strs[j], strs[j+1]) > 0)
        {
            // 交换
        }

多播委托(委托链)
    -> 就好像锁链一样,将多个委托一个一个链在一起,调用第一个委托方法,其后的委托方法依次执行
    -> 语法:
        实现使用:
            委托变量 += 方法名;        // 追加方法,好比在锁链结尾追加锁链
            委托变  量 -= 方法名;        // 移除至指定的方法(不用考虑方法在哪里)
    -> 使用:
        -> 简单的委托链
        -> 带有返回值的委托连
            调用委托连,返回的是最后一个方法的返回值
            如果需要得到委托连中其他方法的返回值,只有一个个调用接收
        -> 如果一个方法出现异常,其后所有方法不在执行

 

 事件(event)
    -> event 是事件定义的关键字
    -> 目标:
        -> 什么是事件
        -> 事件与委托的区别
        -> 如何使用事件(案例)
    -> 第一次接触事件
        WinForm
    -> 事件就是一个委托变量
    -> 等待模块
        // 伪代码
        whie(Consoe.ReadKey().KeyCode != ConsoeInfo.Q)
        {            
        }
    -> 事件与委托的区别
        委托是类型,而刚刚用的是委托的变量(事件是一个特殊的委托变量)
        委托具有灵活性,不安全
            -> 使用委托,注册方法可以使用=和+=
                使用+=叫追加方法,使用=的时候就是注册方法(一旦=以后,委托链中的方法会清空)
            -> 委托在使用的时候为了可以给其添加方法使用了属性或pubic修饰符
                谁都可以调用它
    -> 事件,就是委托变量的阉割版
        -> 不允许使用=赋值,只能使用+=和-=添加和移除方法
        -> 不允许外部调用,只能由内部事件触发方法调用
        
        -> 语法:
            定义委托变量的时候使用
            pubic 委托类型 委托变量;
            改为
            pubic event 委托类型 事件变量;
    -> 说明:
        -> 添加事件

10、窗体传值

11、委托的本质与事件的本质(不作要求,以介绍为主)
    -> 委托的层次级别
        Object
            Deegate
                MuticastDeegate
                    用户定义的委托类型
    -> 委托的内存处理过程
    -> 事件
        -> 事件是一个私有的委托变量和两个方法(remove、add)
            事件的这两个方法可以看做为属性

 

委托和事件的区别:
委托和事件没有可比性,因为委托是类型,事件是对象(可以理解为对委托变量的封装。d),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。(举例子:三种实现事件方式的区别)
因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Deegate就没法进行上面的控制,因此诞生了事件这种语法。add、remove。
事件是用来阉割委托实例的。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能=、不能外部触发事件。
 
委托与事件总结:
委托的作用:
•占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列表要确定)。在实际调用之前,需要为委托赋值,否则为nu。
事件的作用:
•事件的作用与委托变量一样,只是功能上比委托变量有更多的限制。(比如:1.只能通过+=或-=来绑定方法(事件处理程序)2.只能在类内部调用(触发)事件。)
在自定义控件(自己编写控件的时候,会大量用到.编写控件的时候,会写一些事件。但是当这些事件 被触发以后,具体执行的那些事件处理程序是编写控件的人没法确定的。这个时候只能通过事件来占位(调用),具体调用的是哪个方法,由使用控件的人来决定(Cick+=new 委托(方法名);))
 
委托与事件个人理解:
委托是指向具有相同方法签名的方法的变量,可以实现把方法作为参数来传递。(委托类型实质是类,可以理解为:把定义委托类型当成一个用来指向有相同特性的方法的模板,然后定义出具体的变量来指向具体的方法。)
 
事件是委托变量的阉割版,实质是一个私有委托变量和两个委托方法(Add方法和Remove方法),事件是一个受限的委托,只能在定义事件的类的内部去调用,不能在外部直接调用(触发),在外部只能通过+=增加注册方法,通过-=移除指定的方法。
 
二.委托与函数指针的区别
1.委托定义了一种新类,该类代表一组具有特定参数及返回类型的方法。声名了委托类型后,必须创建委托对象(实例化)并使之与特定方法关联。对于静态方法,委托对象直接封装要调用的方法。对于实例方法,必须先创建一个类的实例,然后封装该实例上的一个方法。   
2.委托大体上相当于C中的函数指针。但与函数指针不同的是,委托是面象对象的和类型安全的。   
3.一个委托可以对应多个委托对象,只要方法的签名与委托的最初定义相匹配。委托对象的调用与原方法调用相同。   
4.委托不知道或不关心自己实例对象所封装的方法的细节(什么名字或实现什么功能),只要方法的参数类型和返回类型与该委托的参数类型和返回类型相匹配。
 
匿名方法与Lambda表达式
    -> 调用方法自定义排序
        MySort(strs, 方法);
        // 传统的处理方法,就是先单独写一个判断大小的方法,在调用这个排序
        // 调用MySort方法的使用把比较大小的规则直接写在参数里面
        MySort(strs, {s1.Length > s2.Length});
    -> 匿名方法,没有名字的方法
        -> 就是在代码的执行中定义方法体,运行的时候直接执行(把方法规则写在执行代码中)
        -> 语法:
            委托类型 委托变量 = delegate(参数) { 方法体 };
            int         num      = 1 + 2;

4、 Lambda表达式(匿名方法的一个衍生)
    -> 语法:
        (参数) => 执行体;
        // => 读作goes to
    -> 说明
        -> Lambda表达式是一个表达式(注意)
        -> ()中的参数,如果没有冲突,可以省略类型
        -> Lambda执行体,如果只有一句话,可以省略花括号
        -> 返回值的return可以省略
        -> Lambda表达式执行体中的变量可以引用到外面(*奇异*)
    -> Lambda表达式来源于函数式变成Lisp语言
        Erlang一个函数式编程语言
        函数式编程语言在并操作中应用非常广泛
        Lambda表达式树(晦涩的)
            () => 表达式1
                => 表达式2
                => 表达式3
                => 表达式4
                => 表达式5
=============================================
补充扩展:
C#中的委托、事件和设计模式(转载)
 

推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
author-avatar
温思家羽绒家纺旗舰店
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有