C#中的委托(Delegate)和事件 (Event)详解与使用范例

2023-05-16

一.委托(Delegate)

1.委托(Delegate)简介

最近天气晴雨不定,你因为害怕打游戏时忘记在下雨时收衣服或者在天晴时把衣服挂出去,于是你委托好友小明在天气发生变化时打电话通知你,这就是一种委托.

下面是这种委托的实例代码

//定义一个继承自Delegate类的子类小明,这之后小明就具备被委托的属性
//public为公开,void为返回类型,XiaoMing为类名,(string msg)为传递给注册的方法的参数
public delegate void XiaoMing(string msg);
class Me
{
    //public代表聆听小明的信号是公开的方法,以便小明访问
    //static是为了固定ListenToXiaoMing在内存中的入口以便小明能够找到该方法的入口
    public static void ListenToXiaoMing(string msg)
    {
        if(msg == "Rain")
        {
            Console.WriteLine("下雨了!小明收衣服了!");
        }
        else if(msg == "Sunny")
        {
            Console.WriteLine("天晴了!小明晒衣服了!");

        }
    }
}


class Program
{
    static void Main(string[] args)
    {
        //初始化一个XiaoMing类的实体xiaoMing
        //将我的ListenToXiaoMing注册在xiaoMing上
        //相当于我与小明约定下雨后小明就通知我做出行动(调用ListenToXiaoMing)
        XiaoMing xiaoMing = Me.ListenToXiaoMing;



        //假设今天下雨
        string weather = "Rain";
        
        //小明观察天气
        //将weather参数传递给Me.ListenToXiaoMing方法
        xiaoMing.Invoke(weather);

    }
}

以上代码的输出为

下雨了!小明收衣服了!

值得一提的是,如下代码为创建一个继承自Delegate类的名为XiaoMing的子类,该子类实例只接收void类型方法并且参数类型为(string)的注册,如:void foo(string test){}

public delegate void XiaoMing(string msg);

2.组播委托

你感觉小明的提醒十分靠谱,于是将这件事告诉了同样喜欢玩游戏的小刚,于是小刚也决定请小明在天气发生变化时提醒他,这就是组播委托.

当执行delegate.Invoke()时,将会执行所有注册在该delegate上的方法

以下是这种委托的代码:

public delegate void XiaoMing(string msg);


//你的类
class Me
{
    //public代表聆听小明的信号是公开的方法,以便小明访问
    //static是为了固定ListenToXiaoMing在内存中的入口以便小明能够找到该方法的入口
    public static void MeListenToXiaoMing(string msg)
    {
        if(msg == "Rain")
        {
            Console.WriteLine("下雨了!小明收衣服了!");
        }
        else if(msg == "Sunny")
        {
            Console.WriteLine("天晴了!小明晒衣服了!");

        }
    }
}


//小刚的类
class XiaoGang
{
    
    public static void XiaoGangListenToXiaoMing(string msg)
    {
        if (msg == "Rain")
        {
            Console.WriteLine("下雨了!小刚收衣服了!");
        }
        else if (msg == "Sunny")
        {
            Console.WriteLine("天晴了!小刚晒衣服了!");

        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        //初始化一个XiaoMing类的实体xiaoMing
        //将我的ListenToXiaoMing注册在xiaoMing上
        //相当于我与小明约定下雨后小明就通知我做出行动(调用ListenToXiaoMing)
        XiaoMing xiaoMing = Me.MeListenToXiaoMing;

        //小刚也将自己的XiaoGangListenToXiaoMing注册到被委托人小明身上
        xiaoMing += XiaoGang.XiaoGangListenToXiaoMing;



        //假设今天下雨
        string weather = "Rain";

        //小明观察天气
        //将weather参数传递给Me.ListenToXiaoMing方法
        //和XiaoGang.XiaoGangListenToXiaoMing方法
        xiaoMing.Invoke(weather);

    }
}

运行结果为

下雨了!小明收衣服了!
下雨了!小刚收衣服了!

注意事项:

在使用Delegate子类时,需要用如下代码进行初始化

//方法一 
XiaoMing xiaoMing; 
xiaoMing=Me.MeListenToXiaoMing;
//方法二
XiaoMing xiaoMing=Me.MeListenToXiaoMing;

//错误示范
XiaoMing xiaoMing;
xiaoMing+=Me.MeListenToXiaoMing;

3.事件(event)与委托配合

当你和小刚为小明的靠谱感叹时,天气变化无常的季节结束了,你们不再需要小明通知你们收放衣服了.

你们又有了新的需求----你喜欢在阴天运动,但是小刚喜欢在晴天运动,于是你们请小明吃了一顿饭,请求他在阴天通知你运动,在晴天通知小刚运动,这样的话你们就不用在收到阴天和晴天的消息时花费精力自行判断要不要运动了.

以下是这次委托的代码,小明将会根据不同情况通知不同的人

//好朋友小明类
class XiaoMing
{
    //定义一个继承自Delegate类的委托子类,就像是呼叫是人们通讯的方法
    //而小明的呼叫是继承自呼叫的子类
    public delegate void CallTFirends();


    //以下是事件,是一个用于触发不同委托的字段
    //这是委托你去运动的字段
    public  event CallTFirends CallMe;

    //这是委托小刚去运动的字段
    public event CallTFirends CallXiaoGang;
    
    
    
    //好心的小明用下面的方法时时关注天气
    public void LookForWeather(string weather)
    {
        if (weather == "Cloudy")
        {
            //与下方的CallXiaoMing?.Invoke();具有相同功能
            //即防止小明小刚还没通知喜欢哪种运动天气时进行提醒
            //防止在event还没注册时就被调用
            if (CallMe != null)
            {
                CallMe.Invoke();
            }
        }
        else if(weather == "Sunny")
        {
            CallXiaoGang?.Invoke();
        }

    }

}


//你的类
class Me
{
    //你收到小明的信号会调用以下方法去运动
    public static void MeListenToXiaoMing()
    {
       Console.WriteLine("小明运动啦!");
    }
}


//小刚的类
class XiaoGang
{

    //小刚收到小明的信号会调用以下方法去运动
    public static void XiaoGangListenToXiaoMing()
    {
        Console.WriteLine("小刚运动啦!");
    }
}

class Program
{
    static void Main(string[] args)
    {

        XiaoMing xiaoMing = new XiaoMing();
        //天气为阴天
        string weather = "Cloudy";

        //你注册了callMe的事件,意味通知小明在阴天通知你去运动
        xiaoMing.CallMe += Me.MeListenToXiaoMing;
        //小刚注册了XiaoGang.XiaoGangListenToXiaoMing事件,意味通知小明在晴天通知小刚去运动
        xiaoMing.CallXiaoGang += XiaoGang.XiaoGangListenToXiaoMing;

        //小明观察天气并且提醒对应的人去运动
        xiaoMing.LookForWeather(weather);
       

    }
}

运行结果为

小明运动啦!

细节提示:

1.事件只能在声明它的类中被触发(即例子中在XiaoMing类种才能触发),在声明它的类之外只能订阅和取消订阅。

2.事件的一大作用是方便由声明Delegate的类集中管理而不用每个类自行判断传输过来的信号,如你和小刚不用自行判断传来的天气适合做什么只需要在收到消息后去运动即可.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#中的委托(Delegate)和事件 (Event)详解与使用范例 的相关文章

随机推荐

  • Android中的广播机制

    说明 xff1a 本文是郭霖 第一行代码 第3版 的读书笔记 6 1 广播机制简介 Android中的广播分为两种类型 xff1a 标准广播和有序广播 标准广播 xff1a 完全异步执行的广播 xff0c 在广播发出后 xff0c 所有的B
  • 各种常用默认的端口号

    端口号的范围是从1 xff5e 65535 其中1 xff5e 1024是被RFC 3232规定好了的 xff0c 被称作 众所周知的端口 Well Known Ports xff1b 从1025 xff5e 65535的端口被称为动态端口
  • 序号的结构层次顺序

    数字序号的级别顺序为 xff1a 第一层为汉字数字加顿号 xff0c 例如 xff1a 一 二 三 xff1b 第二层为括号中包含汉字数字 xff0c 例如 xff1a xff08 一 xff09 xff08 二 xff09 xff08 三
  • Abaqus双层混凝土梁三点抗弯(Explicit显式动力学)

    建模过程 1 part 部分 建立两层混凝土棱柱体和三个圆柱体 xff0c 并赋予材料属性 2 装配part xff0c 并在三个圆柱体圆心设立参考点 3 创建分析步 step中创建Dynamic Explicit Time period
  • Linux—生成随机密码

    Linux 小技巧 当我们需要设置十几位长度的密码时 xff0c 可能需要想半天 其实我们可以利用工具来直接生成随机的密码字符串 xff0c 这样又安全又方便 1 urandom 命令 span class token punctuatio
  • MySQL基础学习

    文章目录 MySQL基础学习1 数据库基本操作2 数据的查询2 2 1数据插入2 2 2 单表查询2 2 3 order by语句2 2 4 聚集函数 xff08 aggregate functions xff09 2 2 5 连接查询2
  • C++ 快速读入输出模板(竞赛专用)

    快输快读 xff0c 在算法竞赛中 xff0c 一定程度上可以减小程序的运行时间 xff1a 快读模板1 xff1a inline int read char c 61 getchar int x 61 0 f 61 1 for isdig
  • C#窗体应用实战项目——绩效考核管理系统

    笔者入门C xff0c 熟悉C 语法之后 xff0c 来做一个Winform项目巩固知识 xff0c 记录一下学习过程 一 什么是Winform WinForm 是 Windows Form 的简称 xff0c 是基于 NET Framew
  • Win10家庭版将中文用户名修改为英文用户名

    Win10家庭版将中文用户名修改为英文用户名 前言步骤 前言 由于同学重装系统把用户名设置成中文 win10系统在登陆时自动创建中文文件夹 xff0c 中文路径会影响一些软件的安装和使用 我总结了将中文名修改为英文名的办法 步骤 第一步 x
  • 【已解决】无法加载 DLL“xxx.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。

    目录 异常背景及产生原因解决方法 异常 无法加载 DLL xxx dll 找不到指定的模块 异常来自 HRESULT 0x8007007E 背景及产生原因 C 中采用DLLImport静态调用同事用C 43 43 写的dll算法库时 xff
  • 简单几步实现Ubuntu22.04启用Nvidia显卡

    0 查看已存在的显卡 lspci span class token operator span span class token function grep span VGA 1 禁用之前的驱动 span class token funct
  • Centos配置CA(证书颁发机构)

    文章目录 赛题 1 安装openssl 2 修改根证书存放目录 3 创建根证书存放目录 4 创建根证书 5 检验测试 赛题 7 CA 证书颁发机构 CA 根证书路径 csk rootca csk ca pem 签发数字证书 颁发者信息 仅包
  • ChinaSkills-网络系统管理(2022年全国职业院校技能大赛-模块C-Window部署-02卷-真题 )

    2022 年全国职业院校技能大赛 网络系统管理赛项 模块 B xff1a Windows 部署 卷 II 目 录 一 竞赛说明 4 二 初始化环境 4 xff08 一 xff09 默认账号及默认密码 4 xff08 二 xff09 操作系统
  • Modbus测试工具ModbusPoll与Modbus Slave使用方法

    一 介绍 Modbus Poll xff1a Modbus主机仿真器 xff0c 用于测试和调试Modbus从设备 该软件支持ModbusRTU ASCII TCP IP 用来帮助开发人员测试Modbus从设备 xff0c 或者其它Modb
  • Debian配置WEB服务(lighttpd+fastcgi-php)-IspSrv

    文章目录 赛题安装服务开启fastcgi模块编写php网页文件重启服务防火墙放行端口RouterSrv测试 赛题 WEB 服务 安装 lighttpd xff08 使用其他 web 平台 xff0c 以下功能均不得分 xff09 xff1b
  • Debian配置SSH-AppSrv

    文章目录 赛题编辑配置文件重启sshd服务限制仅允许客户端访问客户端免密钥 赛题 SSH 安装 SSH xff0c 工作端口监听在 19210 xff1b 仅允许 InsideCli 客户端进行 ssh 访问 xff0c 其余所有主机的请求
  • (1)堆栈(顺序栈)

    目录 1 栈的概念 2 顺序栈 栈的顺序存储结构 2 1栈的上溢和下溢 3 栈类的定义 1 C 43 43 2 C 4 栈的抽象数据类型定义 5 实现顺序栈 堆栈的主要操作 定义堆栈 入栈push 出栈pop 判断是否为空isEmpty 已
  • 2021-04-09编程求1000以内的所有“完数”。所谓“完数”是指一个数恰好等于它的因子之和。例如,6是完数,因为6=1+2+3

    编程求1000以内的所有 完数 所谓 完数 是指一个数恰好等于它的因子之和 例如 xff0c 6是完数 xff0c 因为6 61 1 43 2 43 3 include span class token string 34 stdio h
  • Anaconda常用指令

    首先 进入cmd的方法 xff1a win 43 R打开运行窗口 xff0c 然后在运行窗口中输入cmd xff0c 回车 xff0c 进入命令行 然后 输入以下命令 xff1a conda activate 创建环境 xff1a cond
  • C#中的委托(Delegate)和事件 (Event)详解与使用范例

    一 委托 Delegate 1 委托 Delegate 简介 最近天气晴雨不定 你因为害怕打游戏时忘记在下雨时收衣服或者在天晴时把衣服挂出去 于是你委托好友小明在天气发生变化时打电话通知你 这就是一种委托 下面是这种委托的实例代码 定义一个