C#中的代理委托和event关键字

C# Events类和Event详解 C#中的 event 关键字,它与 System.Threading 名称空间中的 events 类没有关系。event 关键字基于委托,而上述 events 类是 .NET 封装器,用于系统范围内的本机事件资源的同步。通过事件使用委托事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模 阅读详情

也叫作委托。事实上,代理就是用于定义指向方法的引用。
比如你在你眼前的程序中要调用另一部分程序的内容(方法或属性),但是,你不能保证函数名或者属性名不发生变化,或者根本程序不可见(不是public或者是DLL的程序)。那么就使用代理。
定义如下

        public delegate UInt32[] getDownLoadParam();
        public delegate void messgeFromDataLayer(Int32 info, Int32 info1, Int32 info2);

        getDownLoadParam m_getDownLoadParam;
        messgeFromDataLayer m_messgeFromDataLayer;

在模块初始化时为他们赋值。

            m_getDownLoadParam = GetDownLoadParam;
            m_messgeFromDataLayer = MessgeFromDataLayer;

函数名可以直接转化为代理类型的对象。这样,你就可以向普通函数一样调用他们了。

m_messgeFromDataLayer(1, 0, 0);

一个完整的使用如下

using System;
namespace sandbox
{
    class DelegateTest
    {
        public delegate void CompareDelegate(int a, int b);

        // 欲传递的方法,它与CompareDelegate具有相同的参数和返回值类型  

        public static void Compare(int a, int b)
        {
            Console.WriteLine((a > b).ToString());
        }



        public static void Main()
        {
            // 创建delegate对象  
            CompareDelegate cd = new CompareDelegate(DelegateTest.Compare);
            // 调用delegate  
            cd(1, 2);
        }
}

除了代理外,C#还有一个常见的语法糖。event关键字。上面代理可以让程序动态调用函数指针处理。但是,如果我们希望的处理函数不止一个,特别是对于界面上。所以,我们引入了event关键字。可以向中间添加若干个代理的实例,将依次调用。
event的声明是event+事件支持的代理名+event名。直接用event名就可以出发事件。一个event可以添加若干个事件处理的代理实例,但他们必须都是一个代理类型的。一个代理类型可以由多个代理的实例。

using System;

namespace sandbox
{
    class DelegateTest
    {

        public static void Main()

        {
            //创建事件源,并将事件处理程序进行注册
            EventSource src = new EventSource();
            src.OnClick += new EventSource.ClickHandler(MyFire1);
            src.OnClick += new EventSource.ClickHandler(MyFire2);
            src.Click();
            System.Console.ReadLine();
        }

        public static void MyFire1(object sender, ButtonClickArgs e)
        {
            Console.WriteLine(e.Clicker+"    hava been shot in 1");
        }
        public static void MyFire2(object sender, ButtonClickArgs e)
        {
            Console.WriteLine(e.Clicker+"    hava been shot in 2");
        }
    }
    class EventSource
    {
        public delegate void ClickHandler(object sender, ButtonClickArgs e);
        public event ClickHandler OnClick;
        public void Click()
        {
            OnClick(this, new ButtonClickArgs() { Clicker = "Signal" });
        }

    }

    public class ButtonClickArgs : EventArgs

    {
        public string Clicker;

    }
}

这种delegate和event共同使用的情景常用语界面的设计

如果你不使用代理,而执意要用public,那么在访问form的子类的对象的值类型成员时,编译器会给出CS1690警告:由于xxx是引用封送类的字段,访问上面的成员可能导致运行时异常。
这是因为form类是MarshalByRefObject的子类,该类旨在设计支持不同程序域的对象进行通信。一般来说,不同程序域的通信有两种方式,第一种就是直接传送对象的副本,另一种是使用代理。MarshalByRefObject使用的的是后一种。当有人要远程访问他的对象是,第一次他会向对方传递代理,然后如果对方调用该代理,就由己方的对象负责执行。
所以,如果你访问form类的对象A所包含的对象B的方法时,就将程序置于依赖远程对象执行的代码的风险之下,所以编译器会发送警告。解决的方法就是把对象B先复制到本地就可以了。

using System;

class WarningCS1690: MarshalByRefObject
{
   int i = 5;

   public static void Main() 
   {
     WarningCS1690 e = new WarningCS1690();
     e.i.ToString();   // CS1690

     // OK
     int i = e.i;//c#是system.int32的别名而已
     i.ToString();
     e.i = i;
   }
}
在windows系统上使用codex出现应用程序无法正常启动(0xc0000022)的解决方案 本文主要介绍了在windows系统上使用codex出现应用程序无法正常启动(0xc0000022)的解决方案,希望能对使用codex的同学们有所帮助。 文章目录 1. 问题描述 2. 原因分析 3. 解决方案 阅读详情

相关推荐

Spring Boot 3.5.4 + LangChain4j实战:用Milvus搭建企业级RAG问答系统(附阿里百炼API配置)

本文详细介绍了如何利用Spring Boot 3.5.4、LangChain4j与Milvus构建企业级RAG问答系统。内容涵盖从架构设计、阿里百炼API安全配置、Milvus部署优化,到RAG检索、会话管理等核心实现,并提供了生产级API设计、监控集成及性能优化等实战经验,旨在帮助开发者打造高可用、可维护的Java AI应用。

weixin_29054399的博客 610

C# 引用其他命名空间的公共变量时的警告:由于"***"是引用封送类的字段,访问上面的成员可能导致运行时异常

编译器警告(等级 1)CS1690 错误消息 由于“member”是引用封送类的字段,访问上面的成员可能导致运行时异常 当您尝试对从 MarshalByRefObject 派生的类成员调用方法、属性或索引器时,并且该成员是值类型时,会出现此警告。若要解决此警告,请将该成员复制到局部变量并对此变量调用方法。下面的示例生成 CS1690: // CS16

站在巨人的肩膀上 8363

Cortex-M异常处理深度解析:从HardFault到调试实战

在嵌入式开发中,Cortex-M系列处理器的异常处理机制是保障系统可靠性的核心。然而,面对HardFault、MemManage、BusFault等异常时,开发者往往陷入迷茫。本文结合SEGGER AN00016和Keil AN209两篇权威文档,深入剖析异常根源、寄存器解析及调试技巧,并通过代码实例演示如何快速定位问题。

汽车电子软件领域知识分享 2533

由于“xx”是引用封送类的字段,访问上面的成员可能导致运行时异常

DataTable dt = fm_main_data.c_data.BJLX;  这段代码提示了异常: 是引用封送类的字段,访问上面的成员可能导致运行时异常; ============================================================================================ 解决: DataTable dt = fm

5277

ESP32蓝牙广播数据自定义指南:让你的设备更容易被手机发现

本文详细介绍了如何通过自定义ESP32蓝牙广播数据提升设备在手机端的可发现性。从广播数据结构、扫描响应优化到跨平台兼容性设置,提供了全面的技术指南和实战代码示例,帮助开发者解决智能硬件开发中的蓝牙连接难题。

weixin_29172201的博客 271

【DDSCAT——离散偶极近似仿真程序05】模型设计Matlab代码:多核壳球 、多核壳圆柱

简洁明了,后面及部分给出的都是模型设计的Matlab代码,这些代码都来自于一篇文章:Chin C W S. Localized Surface Plasmon Resonance with the use of Silver and Titanium Oxide Nanostructures[J]. 2011. 一、设计多个核壳球形结构 1)Matlab代码 ...

XD_Yangf的博客 4260

警告:由于xxx是引用封送类的字段,访问上面的成员可能导致运行时异常

在实现“C#软件开发实例.私人订制自己的屏幕截图工具(六)添加配置管理功能”功能时,遇到警告:由于“Screenshot.Form1.ZoomBoxHeight”是引用封送类的字段,访问上面的成员可能导致运行时异常 解决方案: 对字段对待封装:在需要封装的字段上单击鼠标右键,重构》封装字段: 输入属性名: 使用默认设置,单击应用 ...

无知人生,记录点滴 1422

Infinite-Canvas:一站式AI绘画工作流平台部署与实战指南

在 AI 绘画和内容创作领域,你是否经常遇到这样的困扰:灵感来了,却要在多个工具间来回切换——找素材、写提示词、调整参数、批量生成,整个过程繁琐且低效。创作一个系列作品时,管理不同版本的图片和提示词更是让人头疼。如果你渴望一个能整合所有流程,实现从素材管理、提示词工程到批量出图一站式完成的工作台,那么今天介绍的 Infinite-Canvas 正是为你量身打造的解决方案。 Infinite-Canvas 是一个开源的本地网页应用,它将 AI 绘画的完整工作流集成在一个界面中。无论你是想快速生成单张图片,还是

weixin_28707535的博客 338

在C#中使用代理的方式触发事件

转载自:http://www.yaogg.com/c_xuexi/Article.asp?Id=41354事件(event)是一个非常重要的概念,我们的程序时刻都在触发和接收着各种事件:鼠标点击事件,键盘事件,以及处理操作系统的各种事件。所谓事件就是由某个对象发出的消息。比如用户按下了某个按钮,某个文件发生了改变,socket上有数据到达。触发事件的对象称作发送者(sender),捕获事件并且

david286的专栏 748

解析AI人工智能领域AI芯片的散热技术

当你用ChatGPT写代码、用AI生成高清图片时,背后的AI芯片可能正在“发高烧”——全球TOP500超算的平均功耗已突破10兆瓦,单颗GPU的峰值功耗超过700W(相当于3台家用空调同时运行)。本文将聚焦AI芯片的散热技术,覆盖从基础原理到前沿方案的全链条解析,帮助读者理解“散热为什么比算力更重要”。

AIGC应用创新大全的博客 936

即插即用篇 | 手把手教你 YOLOv11 添加注意力机制 | 适用于【检测任务】【分类任务】【分割任务】【关键点任务】| 20+ 种全打通!

即插即用篇 | 手把手教你 YOLOv11 添加注意力机制 | 适用于【检测任务】【分类任务】【分割任务】【关键点任务】| 20+ 种全打通!

Coding... 2831

C# 委托 代理

C# 委托、代理举例如下 B的show方法绑定到A的show方法,使得A在show时B也show C#中委托代理用法 定义delegate对象类型,如: public delegate void myEventHandler(object sender ,EventArgs e); 其中 sender代表触发事件的本身,EventArgs 是事件参数类 定义事件参数类,这个可

本 的专栏 1137

【已解决】WorkBuddy 国内版与国际版共存 + 关闭自动更新 教程

本文介绍在Windows系统中同时安装并共存WorkBuddy国内版与国际版的完整方案,通过修改product.json文件关闭启动自动更新,修复缓存配置污染问题,确保两版本互不干扰、数据独立。重点解决因共享身份标识导致的更新源错乱、进程锁冲突及自动覆盖风险,提供命令行备份与修改步骤,并强调手动升级时需避免使用应用内更新功能,以规避平台参数错位缺陷。

人生是一场修行 1514

C#设计模式之订阅发布模式

什么是Pub-Sub 发布订阅是一种设计模式,它允许应用程序组件之间进行松散耦合。 其实订阅发布设计中主要是发布者生成事件通道,用于在不了解任何订阅者存在的情况下通知订阅者。 当然委托EventHandlers和Event关键字vb.net教程在此事件处理机制中担任着重要的角色。下面我们来看看如何使用它们。 Pub和Sub的使用 首先我们看一个简单地订阅发布 c#教程模式. 定义一个Action委托,无返回值. namespace PubSubPattern { public class Pub

chinaherolts2008的博客 507

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

艾伟_转载:.NET委托:一个C#睡前故事

  英文版原作者:Chris Sells(www.sellsbrothers.com)   翻译:袁晓辉(www.farproc.com http://blog.csdn.net/uoyevoli)   原文地址: http://dev.csdn.net/article/82/82644.shtm   紧耦合   从前,在南方一块奇异的土地上,有个工人名叫彼得,他非常勤奋,对他的老板总是百...

weixin_33859504的博客 85

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

小知识(七):代理&事件

代理delegate: 对象引用指向某个特定类型的对象。 代理指向某个特定类型的方法。 代理四步: 定义自定义代理类:public delegate void first(int i); 实例化代理类:first MyDelegate = null; 实例添加方法:MyDelegate += new...

ade61966的博客 158

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C#委托(Delegate)和事件(Event)

事件的拥有者(即定义事件的对象)在适当的时候触发事件,通知所有订阅了该事件的监听者(即订阅了事件的对象)。在发布-订阅模式中,发布者(即拥有事件的对象)发布消息(即触发事件),而订阅者(即订阅了事件的对象)则接收并处理这些消息。这个委托类型定义了事件的签名(即事件的参数和返回类型),以及可以订阅该事件的方法的类型。事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表,这被称为委托的多播,也叫组播。

wangyuhua_的博客 1075

C# 委托(Delegate)与事件(Event)

C# 委托是.NET Framework 使用的一种类型安全的函数指针。委托通常用于实现回调和事件侦听器。委托是引用类型。但是委托不是引用对象,而是引用方法。.NET 框架内置的委托事件(Event)基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。

hccee的博客 2683

event与delegate的区别

首先,通过加入event关键字,在编译的时候编译器会自动针对事件生成一个私有的字段(与此事件相关的委托),以及两个访问器方法,即add访问器方法以及remove访问器方法,用于对事件的注册及注销(对事件使用+=及-=操作时就是调用的这两个方法)。 我想你们的问题主要是,实际上声明一个委托类型的字段也可以实现这些功能。 实际上之所以采用event而不直接采用委托,实际上还是为了封装。可以设想一下

Magina3的专栏 7482

c# 创建委托 消息订阅_C#设计模式之订阅发布模式

什么是Pub-Sub发布订阅是一种设计模式,它允许应用程序组件之间进行松散耦合。其实订阅发布设计中主要是发布者生成事件通道,用于在不了解任何订阅者存在的情况下通知订阅者。当然委托EventHandlers和Event关键字在此事件处理机制中担任着重要的角色。下面我们来看看如何使用它们。Pub和Sub的使用首先我们看一个简单地订阅发布模式.定义一个Action委托,无返回值.namespa...

weixin_39837607的博客 304

C#委托

Delegate,委托(或代理)是这样一种数据类型:它的变量可以引用到某一个符合要求的方法上,通过委托可以间接地调用该方法。   C#的委托类似于C语言的函数指针,区别在于C#的委托是面向对象的。   我们可以这样认为:在纯粹的面向对象语言C#中,方法也是一种特殊对象,对象的行为就是方法的行为,对象的属性是方法的返回值和参数列表。既然可以将方法认定为对象,那该对象也可以抽象出类来。这...

anshi5303的博客 150

C#中的“代理”和“事件”

事件(event)是一个非常重要的概念,我们的程序时刻都在触发和接收着各种事件:鼠标点击事件,键盘事件,以及处理操作系统的各种事件。所谓事件就是由某个对象发出的消息。比如用户按下了某个按钮,某个文件发生了改变,socket上有数据到达。触发事件的对象称作发送者(sender),捕获事件并且做出响应的对象称作接收者(receiver),一个事件可以存在多个接受者。 在异步机制中,事件是线程之间进行...

ljsql的专栏 462

C# event 事件系统

声明事件 首先我们需要声明事件,也就是创造事件。 public event EventHandler RaiseCustomEvent; public event CustomEventHandler RaiseCustomEvent; public event EventHandler<CustomEventArgs> RaiseCustomEvent; 解释(有三种方法):...

别人不知道的程序人生 1095

在C#中使用代理的方式触发事件 (委托和事件 )(一)(转)

事件(event)是一个非常重要的概念,我们的程序时刻都在触发和接收着各种事件:鼠标点击事件,键盘事件,以及处理操作系统的各种事件。所谓事件就是由某个对象发出的消息。比如用户按下了某个按钮,某个文件发生了改变,socket上有数据到达。触发事件的对象称作发送者(sender),捕获事件并且做出响应的对象称作接收者(receiver),一个事件可以存在多个接受者。 在异步机制中,事件是线程之间进行通...

weixin_30346033的博客 214

C#中的委托delegate 与 事件 event

一. 委托delegate 1.理解委托 可以将委托delegate理解为函数指针,声明一个委托,实际上就是声明一个指向绑定函数的指针。当然,C#中是没有指针这个概念的,这种类比可以方便自己理解。 比如,小绿委托小蓝帮自己买一杯酸奶,动作的最终执行者实际是小蓝,小绿只需要告知小蓝,成功建立起联系即可。 1 class cc 2 { 3 4 ...

weixin_30471065的博客 156
上一篇: JAVA C# C/C++比教学:泛型
下一篇: C#和XML
define_us
博客等级 码龄14年 157粉丝 531原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值