• C#复习总结4


    第十三章 委托

    1. 什么是委托

      委托就是函数的指针。

    其和类相似,其实就是用户自定义的引用类型。

    委托是包含有序方法列表的对象,这些方法具有相同的签名和返回类型。

    MyDel delvar = new MyDel(myInstObj.mym1); < == > MyDel delvar = myInstObj.mym1; //两者之间存成隐式转换。

    委托 中还存在给委托赋值,这样会重新指向,组合委托等等。

    委托可以添加方法也可以移除方法。 运算符: += -=

    调用委托就和调用函数是一样的。

    匿名方法:就是没有了 具体的的实例化后的方法名,只有函数体。

    注意作用域的范围:

    利用正则表达式,可以简化 委托。

     

    代码如下:

    1.    delegate void PrintFunction();//定义一个没有返回值和参数的委托类型
    2.    delegate void MyDel(ref int x);//引用参数
    3.    class Test
    4.    {
    5.        public void Print1()
    6.        {
    7.            Console.WriteLine("Print1 --- instance");
    8.        }
    9.        public static void Print2()
    10.        {
    11.            Console.WriteLine("Print2 ----- static");
    12.        }
    13.        public void ADD2(ref int x)
    14.        {
    15.            x += 2;
    16.        }
    17.        public void ADD3(ref int x)
    18.        {
    19.            x += 3;
    20.        }
    21.    }
    22. //调用
    23.           //委托是指持有一个或多个方法的对象,说白了,其实就是函数指针
    24.            //也可以理解为用户自定义的引用类型
    25.             //可以把delegate看成是一个包含有序方法列表的对象,这些方法具有相同的签名和返回类型
    26.             //调用列表中的方法可以是静态方法也可以是实例方法
    27.             //一般先申明,然后创建委托对象。一般我们可以通过+=来组合委托
    28.             //MyDel delA = MyIntObj.MyM1;//都是某个方法的名称,也就是其指针了
    29.             //MyDel delB = MyIntObj.MyM2;
    30.             //MyDel delC = delA + delB;
    31.             Test test = new Test();//创建一个测试类实例
    32.             PrintFunction pf99;//创建一个空委托
    33.             pf99 = test.Print1;//实例化并初始化该委托
    34.             //也可以 pf99 = new PrintFunction(test.Print1);//可以省略
    35.             pf99 += Test.Print2;//给委托添加3个另外的方法
    36.             pf99 += test.Print1;
    37.             pf99 += Test.Print2;
    38.             if (pf99 != null)
    39.             {
    40.                 pf99();//确认委托有方法,并调用委托(无参方法)
    41.             }
    42.             else
    43.             {
    44.                 Console.WriteLine("Delegate is empty!");
    45.             }
    46.             //调用带返回值的委托方法,只需在其他方法中有返回值即可,其执行的是最后一个方法的返回值。
    47.             //调用带引用参数的委托 参数值会根据调用列表中的一个或多个方法的返回值而改变。
    48.             MyDel mydel = test.ADD2;
    49.                  mydel += test.ADD3;
    50.  
    51.             int x = 5;
    52.             mydel(ref x);
    53.  
    54.             Console.WriteLine("Value: {0}", x);
    55.  
    56.             //匿名方法
    57.             //匿名方法是初始化委托是内联声明的方法,即不需要函数了,而是在委托内部自定义函数
    58.             //匿名方法的参数列表必须在参数数量,参数类型与位置,修饰符三个方面与委托匹配。
    59.             //当然,有时候,我们也可以省略参数列表中的数据声明。params参数必须放在最后。
    60.             //delegate void Mydel(int x, params int[] y) ;
    61.             //Mydel mydel = delegate(int x, int[] y){ };
    62.             // Lambda 表达式
    63.             // Mydel mydel = delegate(int x){return x + 1};//匿名方法
    64.             // Mydel mydel = (int x) => {return x + 1}; //Lambda 表达式
    65.             // Mydel mydel = x => x + 1;

     

    第十四章 事件

    1. 发布者与订阅者模式

      发布者就是数据的发送端,订阅者是数据的接收端,但是呢,订阅者必须先在发布者这一端注册才行。

       

      需要在事件中使用的代码有5个部分:

      对应的代码如下:

      //简单点理解:订阅者订阅事件,发布者触发事件,订阅者执行事件处理程序。

       

      利用系统的事件有一个好处不用自己单独在声明委托了,但是不能从发布者传递数据到订阅者去,怎么办?

      通过扩展的EventArgs来实现。其实,只需要声明一个派生自EventArgs类即可。

      代码如下:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5.  
    6. namespace CsharpStart
    7. {
    8.     delegate void Hander();//声明委托
    9.     //发布者类
    10.     class Incrementer
    11.     {
    12.         public event Hander CountedADozen;//创建事件并发布 (事件是特殊的委托)
    13.         public void DoCount()
    14.         {
    15.             for (int i = 0; i < 100; i++) //事件调用函数,或者称为触发事件函数
    16.             {
    17.                 if (i % 12 ==0 && CountedADozen != null)
    18.                 {
    19.                     CountedADozen();//每增加12,事件触发一次
    20.                 }
    21.             }
    22.         }
    23.     }
    24.     //订阅者类
    25.     class Dozens
    26.     {
    27.         public int DozensCount { get; private set; }
    28.  
    29.         public Dozens(Incrementer incrementer)//以发布者类为参数
    30.         {
    31.             DozensCount = 0;
    32.             incrementer.CountedADozen += IncrementerDozensCount;//订阅事件(为事件CountedADozen增加方法)
    33.         }
    34.         void IncrementerDozensCount()
    35.         {
    36.             DozensCount++; //声明事件处理程序
    37.         }
    38.     }
    39.  
    40. //系统自带的委托类型
    41.     public delegate void EventHandler(object sender, EventArgs e);
    42. //其中,第一个参数是用来保存触发事件的对象的引用。
    43.     //第二个参数用来保存状态信息,指明什么类型适用于该程序。
    44.   //用系统自带的委托的话,就不需要自定义委托类型了
    45.     //发布者类
    46.     class Incrementer1
    47.     {
    48.         public event EventHandler CountedADozen1;//创建事件并发布 (事件是特殊的委托)
    49.         public void DoCount()
    50.         {
    51.             for (int i = 0; i < 100; i++) //事件调用函数,或者称为触发事件函数
    52.             {
    53.                 if (i % 12 == 0 && CountedADozen1 != null)
    54.                 {
    55.                     CountedADozen1(this,null);//每增加12,事件触发一次
    56.                                               //触发事件时使用EventHandler的参数
    57.                 }
    58.             }
    59.         }
    60.     }
    61.     //订阅者类
    62.     class Dozens1
    63.     {
    64.         public int DozensCount1 { get; private set; }
    65.  
    66.         public Dozens1(Incrementer1 incrementer1)
    67.         {
    68.             DozensCount1 = 0;
    69.             incrementer1.CountedADozen1 += IncrementerDozensCount1;//订阅事件
    70.         }
    71.         void IncrementerDozensCount1(object sender,EventArgs e)//事件处理程序的签名(特征)
    72.                                                          //必须和系统的委托的签名相匹配
    73.         {
    74.             DozensCount1++; //声明事件处理程序
    75.         }
    76.     }
    77.  
    78.   //如何传递数据到事件处理程序中
    79.     public class IncrementerEventArgs : EventArgs
    80.     {
    81.         public int IterationCount { get; set; }
    82.     }
    83.  
    84.     class Incrementer2
    85.     {
    86.         public event EventHandler<IncrementerEventArgs> CountedADozen2;//使用自定义类的泛型委托
    87.  
    88.         public void DoCount2()
    89.         {
    90.             IncrementerEventArgs args = new IncrementerEventArgs();//使用自定义的类对象
    91.             for (int i = 0; i < 100; ++i)
    92.             {
    93.                 if (i % 12 == 0 && CountedADozen2 != null)
    94.                 {
    95.                     args.IterationCount = i;//携带的参数
    96.                     CountedADozen2(this, args);//可以理解为sendmessage
    97.                 }
    98.             }
    99.         }
    100.     }
    101.  
    102.     class Dozens2
    103.     {
    104.         public int DozensCount2 { get; set; }
    105.         public Dozens2(Incrementer2 incrementer)
    106.         {
    107.             DozensCount2 = 0;
    108.             incrementer.CountedADozen2 += IncrementDozensCount;//订阅事件
    109.         }
    110.         public void IncrementDozensCount(object sender, IncrementerEventArgs e)//事件处理程序
    111.         {
    112.             Console.WriteLine("Incremented at iteration : {0} in {1}",e.IterationCount,sender.ToString());
    113.             DozensCount2++;
    114.         }
    115.     }
    116. }
    117.  
    118. //调用
    119.  //1、发布者/订阅者模式,当一个特定的程序事件发生时,程序的其他部分可以得到该事件
    120.             //已经发生了的通知,并执行相应的 事件处理程序。调用(invoke)
    121.             //5个部分: 1)声明委托。 发布者: 2)创建事件并发布 3)触发事件
    122.             // 订阅者: 4)订阅事件 5)事件处理程序
    123.             Incrementer incrementer = new Incrementer(); //实例化
    124.             Dozens dozensCounter = new Dozens(incrementer);
    125.             incrementer.DoCount();//触发事件,调用事件。
    126.             Console.WriteLine("Number of dozens = {0}",dozensCounter.DozensCount);
    127.             //2、使用系统定义的EventHandler委托
    128.             Incrementer1 incrementer1 = new Incrementer1(); //实例化
    129.             Dozens1 dozensCounter1 = new Dozens1(incrementer1);
    130.             incrementer1.DoCount();//触发事件,调用事件。
    131.             Console.WriteLine("Number of dozens1 = {0}", dozensCounter1.DozensCount1);
    132.             //3、通过扩展的EventArgs来传递数据,简单的说就是通过派生类来实现
    133.             Incrementer2 incrementer2 = new Incrementer2();
    134.             Dozens2 dozensCounter2 = new Dozens2(incrementer2);//实例化
    135.             incrementer2.DoCount2();//触发事件
    136.  
    137.             //4、我们还可以通过 -= 来移除事件。
    138.             //我们在添加事件的时候,不仅仅可以从构造方法中添加(订阅)事件,也可以
    139.             //在实例化后,在main函数中订阅事件。
    140.  
    141.             //5、事件访问器 我们可以为事件定义事件访问器 add与remove
  • 相关阅读:
    二、Cocos2dx概念介绍(游戏开发中不同的坐标系,cocos2dx锚点)
    (2)入门指南——(7)添加jquery代码(Adding our jQuery code)
    Citrix 服务器虚拟化之三十一 XenApp 6.5负载均衡
    CSS——inline-block属性
    VMware Workstation(虚拟机软件) V10.0 简体中文版可以安装了
    [.NET MVC4 入门系列01]Helloworld MVC 4 第一个MVC4程序
    ElasticSearch NEST笔记
    什么是REST API?
    ArrayList与List<T>笔记
    C# Socket SSL通讯笔记
  • 原文地址:https://www.cnblogs.com/zhuxuekui/p/4162656.html
Copyright © 2020-2023  润新知