• C#之泛型、委托、事件及其使用


    一、泛型

            1.泛型的概念

                    优点:增加类型安全,简化编码

                    常见的泛型有:泛型类泛型方法

            2.定义泛型类

    1. public class Stack<T> {}
    2. //T为占位符,表示一个通用数据类型,使用时用实际类型代替
    3. //T可以很多个,以逗号隔开

            3.定义泛型成员和泛型方法

    1. private T[] stack; //泛型容器
    2. public void Push(T item);
    3. public T Pop(); //泛型方法

            4.泛型调用

    1. MyStack<int> stack1 = new MyStack<int>(5); //实例化泛型类
    2. stack1.Push(1); //使用泛型类的泛型方法

            5.default关键字

                    泛型类在初始化时必须指明通用数据类型(不能假定类型),所以一般不允许无参构造函数。故使用default关键字

    1. class MyClass <T1,T2>
    2. {
    3. private T1 obj1;
    4. private MyClass()
    5. {
    6. //obj1 = null; --无效
    7. //obj1 = new T1(); --未指明通用参数类型,无法使用
    8. obj1 = default(T1); //若T1为指定类型则赋值null;为值类型则赋值0;为结构类型则视具体成员类型而定(0或null)
    9. }
    10. }

            6.泛型约束

                    使用where关键字标记在声明后、类体前。用于限定通用类型的种类。可以限定值类型、引用类型、基类类型、接口类型、含无参构造函数的引用类型

    1. class MyClass <T1,T2,T3>
    2. where T1:struct //类型必须为值类型
    3. where T2:class //必须为值类型
    4. where T3:new() //必须有一个无参数构造方法,必须放在最后
    5. {
    6. }

    二、委托

            1.委托的概述

                    委托是一种全新的面相对象语言特性,运行在.Net平台;基于委托,开发事件驱动将会变得相当方便;委托可以视为一种数据类型,可以定义变量,但其是一种特殊的变量。

                    委托定义的变量仅能接收方法(可以理解委托是方法指针

                    委托的映射关系

             2.委托的定义和使用

    1. //声明委托(定义一个方法原型)需要声明返回值+参数类型和个数
    2. public delegate int CalculatorDelegate(int a,int b);
    3. //根据委托定义一个具体方法
    4. static int Add(int a,int b)
    5. { return a+b; }
    6. //调用委托(需要先创建委托对象)--可以在另一个类中
    7. CalculatorDelgate objCal = new CalculatorDelgate (Add);
    8. int reslut = objCal(10,20);
    9. //委托的动态调度(非首次时候使用)
    10. objCal -= Add; //断开委托关联
    11. objCal += Sub; //关联委托关联

            3.利用委托实现跨窗体通信

    1. //主窗体代码
    2. //1-声明委托
    3. public delegate void ShowCounter(string counter);
    4. //2-实现原型
    5. private void Receiver(string counter)
    6. {
    7. this.lblCounter.Text = counter;
    8. }
    9. //3-将子窗体委托变量与主窗体关联
    10. FrmOther objFrm = new FrmOther();
    11. objFrm.msgSender = this.Receiver;
    12. objFrm.Show();
    1. //从窗体代码
    2. //创建委托对象
    3. public ShowCounter msgSender;
    4. //调用
    5. counter++;
    6. if(msgSender !=null)
    7. {
    8. msgSender(counter.ToString());
    9. }

            4.利用委托实现主窗体向子窗体的广播

    1. //主窗体代码
    2. //1-声明委托
    3. public delegate void ShowCounter(string counter);
    4. //2-创建委托对象
    5. public ShowCounter msgSender;
    6. //3-实例化子窗体并关联委托
    7. FrmOther objFrm1 = new FrmOther();
    8. FrmOther objFrm2 = new FrmOther();
    9. this.msgSender += objFrm1.Receiver();
    10. this.msgSender += objFrm1.Receiver();
    11. //4-使用Invoke传值
    12. this.msgSender.Invoke(counter.ToString()); //所有关联了的委托都可以收到
    1. //从窗体代码
    2. //1-根据委托创建方法(接收委托传递的信息)
    3. private void Receiver(string counter)
    4. {
    5. this.lblCounter.Text = counter;
    6. }

    三、事件

            1.事件的概述

                    事件有两个参与者:发送者(sender),即对象本身,当对象本身状态发生变化时触发事件,并通知接受者。

                                                     接受者(reciver),用来处理时间,在发送者触发一个事件后悔自动执行的内容。

            2.事件的定义及应用

    1. //发送者代码
    2. //1-创建委托
    3. public delegate void delegateSendMsg(string msg);
    4. //2-定义一个事件
    5. public event delegateSendMsg SendMsgEvent;
    6. //3-激发事件
    7. SendMsgEvent(txtMsg.Text);
    8. //4-关联接受者和事件
    9. FrmClient objClient = new FrmClient();
    10. SendMsgEvent += new delegateSendMsg(objClient.EventResponse);
    1. //接受者代码
    2. public void EventResponse(string msg)
    3. {
    4. this.txtMsg.text=msg;
    5. }
    1. //从窗体事件关联到主窗体
    2. FrmClient objCli = new FrmClient();
    3. objCli.SendMsgEvent += new delegateSendMsg(this.ShowMsg_SendMsgEvent);

    四、委托和事件的对比

            1.相同点

                    事件对象本质是一个私有的委托对象,都有Add和Remove

            2.不同点

                    委托对象私有化之后不能直接赋值

    1. objCli.SendMsgEvent = null; //无法编译,不能直接赋值
    2. objCli.SendMsgEvent += new delegateSendMsg(this.ShowMsg_SendMsgEvent); //必须使用+=

  • 相关阅读:
    flutter 开发中的问题与技巧
    LeetCode307 周赛(补记)
    ​数据库原理及应用上机(实验二 SQL数据定义功能实验)
    【前端系列】前端如何使用websocket发送消息
    《论文阅读》R-NET: MACHINE READING COMPREHENSION WITH SELF-MATCHING NETWORKS
    11、综合应用案例
    全民健康生活方式行动日,天猫健康联合三诺生物推出“15天持续测糖计划”
    Springboot、Mybatis(Mybatis-plus) 、Mysql
    16.Xaml WrapPanel控件 ---> 流面板
    生成模型的中Attention Mask说明
  • 原文地址:https://blog.csdn.net/weixin_37878740/article/details/126067672