如果事件在 .NET 中作为委托实现,那么 .event IL 部分的意义何在?

2024-03-25

我在 Stack Overflow 上看到了一些非常好的问题,涉及委托、事件以及这两个功能的 .NET 实现。特别提出一个问题,“C# 事件在幕后如何工作? https://stackoverflow.com/questions/213638/how-do-c-events-work-behind-the-scenes#213651”,给出了一个很好的答案,很好地解释了一些微妙的观点。

上述问题的答案说明了这一点:

当您声明类似字段的事件时 ...编译器生成方法 和一个私有字段(相同类型 作为代表)。班级内, 当您引用 ElementAddedEvent 时 你指的是领域。外部 班级,你指的是 场地

同一问题链接的 MSDN 文章(“现场活动 http://msdn.microsoft.com/en-us/library/aa664455.aspx") adds:

引发事件的概念是 完全相当于调用 活动代表代表 — 因此,没有特殊的语言 用于引发事件的构造。

为了进一步检查,我构建了一个测试项目,以便查看事件和委托编译为的 IL:

public class TestClass
{
    public EventHandler handler;
    public event EventHandler FooEvent;

    public TestClass()
    { }
}

我期待代表领域handler和事件FooEvent编译为大致相同的 IL 代码,并使用一些附加方法来包装对编译器生成的访问FooEvent场地。但生成的 IL 并不完全符合我的预期:

.class public auto ansi beforefieldinit TestClass
    extends [mscorlib]System.Object
{
    .event [mscorlib]System.EventHandler FooEvent
    {
        .addon instance void TestClass::add_FooEvent(class [mscorlib]System.EventHandler)
        .removeon instance void TestClass::remove_FooEvent(class [mscorlib]System.EventHandler)
    }

    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        // Constructor IL hidden
    }

    .field private class [mscorlib]System.EventHandler FooEvent
    .field public class [mscorlib]System.EventHandler handler
}

由于事件只不过是编译器生成的委托add and remove方法,我没想到会看到事件被比 IL 中的处理方式更多。但是添加和删除方法是在开始的部分中定义的.event, not .method和正常方法一样。

我的最终问题是:如果事件只是作为具有访问器方法的委托来实现,那么拥有一个事件有什么意义呢?.eventIL部分?如果没有这个,它们不能通过使用 IL 来实现吗?.method部分?是.event相当于.method?


我不确定这是否令人惊讶......与属性与字段相同(因为属性在与事件相同的函数之前:通过访问器封装):

.field public string Foo // public field
.property instance string Bar // public property
{
    .get instance string MyType::get_Bar()
    .set instance void MyType::set_Bar(string)
}

还有-活动do not提及有关字段的任何内容;他们only定义访问器(添加/删除)。委托支持者是一个实现细节;碰巧的是,类似字段的事件将一个字段声明为支持成员 - 与自动实现的属性将一个字段声明为支持成员的方式相同。其他实现也是可能的(并且非常常见,尤其是在表单等中)。

其他常见的实现:

稀疏事件(控件等)-EventHandlerList(或类似):

// only one instance field no matter how many events;
// very useful if we expect most events to be unsubscribed
private EventHandlerList events = new EventHandlerList();
protected EventHandlerList Events {
    get { return events; } // usually lazy
}

// this code repeated per event
private static readonly object FooEvent = new object();
public event EventHandler Foo
{
    add { Events.AddHandler(FooEvent, value); }
    remove { Events.RemoveHandler(FooEvent, value); }
}
protected virtual void OnFoo()
{
    EventHandler handler = Events[FooEvent] as EventHandler;
    if (handler != null) handler(this, EventArgs.Empty);
}

(以上内容几乎是 Windows 窗体事件的支柱)

外观(尽管这会让“发送者”有点困惑;一些中间代码通常很有帮助):

private Bar wrappedObject; // via ctor
public event EventHandler SomeEvent
{
    add { wrappedObject.SomeOtherEvent += value; }
    remove { wrappedObject.SomeOtherEvent -= value; }
}

(以上也可用于有效地重命名事件)

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

如果事件在 .NET 中作为委托实现,那么 .event IL 部分的意义何在? 的相关文章

  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 为什么我不能用 `= delete;` 声明纯虚函数?

    Intro 纯虚函数使用通用语法声明 virtual f 0 然而 自 c 11 以来 有一种方法可以显式地传达non existence 特殊 成员函数的 Mystruct delete eg default constructor Q
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 使用 Storyboard 时获取 NSManagedObjectContext

    目标是获取当前的 NSManagedObjectContext 以便使用 Core Data 在 iOS 4 3 中 我将 UINavigationController 的委托设置为 AppDelegate 如下所示 在 AppDelega
  • 使用post方法将多个参数发送到asp.net core 3 mvc操作

    使用 http post 方法向 asp net mvc core 3 操作发送具有多个参数的 ajax 请求时存在问题 参数不绑定 在 dot net 框架 asp net web api 中存在类似的限制 但在 asp net mvc
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • Clang 编译器 (x86):80 位长双精度

    我正在尝试在 x86 Windows 平台上使用本机 80 位长双精度 海湾合作委员会选项 mlong double 80 https gcc gnu org onlinedocs gcc x86 Options html似乎不适用于 cl
  • 显示异常时的自定义错误消息:从客户端检测到潜在危险的 Request.Form 值

    我在我的 Web 应用程序中使用 ASP NET 的登录控件 当发生此异常时 我想在标签上显示一种有趣的错误类型System Web HttpRequestValidationException A potentially dangerou
  • POCO HTTPSClientSession 发送请求时遇到问题 - 证书验证失败

    我正在尝试使用 POCO 库编写一个向服务器发出 HTTPS 请求的程序 出于测试目的 我正在连接到具有自签名证书的服务器 并且我希望允许客户端进行连接 为了允许这种情况发生 我尝试安装InvalidCertificateHandler这是
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • 当前的 c++ 工作草案与当前标准有何不同

    通过搜索该标准的 PDF 版本 我最终找到了这个链接C 标准措辞草案 http www open std org jtc1 sc22 wg21 docs papers 2012 n3376 pdf从 2011 年开始 我意识到我可以购买最终
  • 基于xsd模式生成xml(使用.NET)

    我想根据我的 xsd 架构 cap xsd 生成 xml 文件 我找到了这篇文章并按照说明进行操作 使用 XSD 文件生成 XML 文件 https stackoverflow com questions 6530424 generatin
  • 生产代码中的 LRU 实现

    我有一些 C 代码 需要使用 LRU 技术实现缓存替换 目前我知道两种实现LRU缓存替换的方法 每次访问缓存数据时使用时间戳 最后比较替换时的时间戳 使用缓存项的堆栈 如果最近访问过它们 则将它们移动到顶部 因此最后底部将包含 LRU 候选
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • 转到定义:“无法导航到插入符号下的符号。”

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我今天突然开始在我的项目中遇到一个问题 单击 转到定义 会出现一个奇怪的错误 无法导航到
  • 使用 C# 从 DateTime 获取日期

    愚蠢的问题 给定日期时间中的日期 我知道它是星期二 例如我如何知道它的 tue 2 和 mon 1 等 Thanks 您正在寻找星期几 http msdn microsoft com en us library system datetim
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop

随机推荐

  • 如何从 .wav 文件中提取特定频率范围?

    I m really声音处理方面的新知识 所以也许我的问题很简单 我想要做的是使用 R 从 wav 文件中提取特定的频率范围 假设为 150 400 Hz 换句话说 我想创建另一个波形文件 wave2 其中仅包含我想要的频率分量 指定 15
  • Github Actions 和 npm - npm:找不到命令

    我已经在 github actions 上创建了一个部署操作 这一切都适用于composer install 和 git pull master 分支 然而 在我的数字海洋水滴上 我遇到了问题bash line 4 npm command
  • 调用相机时,三星 Intent For OnActivityResult 为 Null

    我正在使用以下代码从相机获取图片 除三星外 其他手机均运行良好 请让我知道我做错了什么 final File root new File Environment getExternalStorageDirectory File separa
  • 鼠标按下事件计时

    我被要求编写代码 使其能够单击 Excel 中的图像并在其顶部添加形状 这是物理治疗师的身体图 该形状将指示患者疼痛的部位 我的代码通过使用 ActiveX 图像控件的鼠标按下事件来完成此操作 Private Sub bodypic Mou
  • 如何获取去电连接状态

    在我的应用程序开发中 我需要在拨出电话接通时进行振动 但无法获取呼叫已接听状态 我读过一些关于这个问题的主题 例如 去电状态 https stackoverflow com questions 2099782 outgoing call s
  • 为什么我的指令的链接函数从未被调用?

    我有这个指令 hpDsat directive ngElementReady function return restrict A link function scope element attributes put watches her
  • 自定义 HTML 元素

    The HTML 规范 https html spec whatwg org multipage scripting html custom elements描述了存储在中的几种元素自定义元素注册表 内置元素如 a 由内置子类表示HTML元
  • 如何查看 linq 查询生成的 sql

    只是试图获取由 linq 查询生成的 sql 使用 Linq2Sql dc GetCommand query CommandText see http msdn microsoft com en us library system data
  • 如何从字符串中解析 ODataQueryOptions?

    我必须在符合 OData 规范的 ASP NET API 上为 EF6 实体提供一些读取端点 实体检索基于接受实体的函数而工作良好System Web Http OData Query ODataQueryOptions
  • 并行运行异步任务

    在 RxJS 中 当您想要按顺序运行 http 请求时 您可以将它们链接起来 但我不清楚如何并行运行请求 我在例子中看到http reactive extensions github io learnrx http reactive ext
  • 如何在Python中使用lambda排序

    我正在尝试按属性对某些值进行排序 如下所示 a sorted a lambda x x modified reverse True 我收到此错误消息
  • 向下滚动 Instagram 框中的关注者/关注列表

    你好 我一直在寻找一种解决方案来向下滚动 Instagram Box 中的关注者 关注者列表 我所做的步骤如下 打开用户A的IG资料 点击 关注者 按钮 IG 框中会出现一个包含 12 个关注者列表的框 一旦关注者列表显示出来 当我使用以下
  • Grails hasOne 和 hasMany 相同的域

    我有这样的域名 class Team hasOne leader Person hasMany member Person class Person belongsTo team Team 但是生成表后 team表中并没有leader id
  • NSGA-II(非支配排序算法)

    我研究过非支配排序算法 nsga II 此链接给出了算法 http church cs virginia edu genprog images 2 2f Nsga ii pdf http church cs virginia edu gen
  • “无法初始化代理 - 无会话”且有可用的打开会话

    我使用 JSF 2 MyFaces 2 1 7 和 Primefaces 3 4 2 CDI Weld servlet 1 1 10 JPA 2 Hibernate 4 1 7 和 Lombok 0 11 2 所有这些都在 Tomcat 6
  • 为什么在使用 setScaleX() 时,motionEvent.getX() 返回不一致的值?

    我的子视图驻留在 ViewGroup 中 我想用捏来缩放 缩放 孩子 我正在使用 setScaleX Y 来缩放孩子 比例是在 OnTouch 中根据 2 个指针之间的距离计算的 但是当我设置子级的比例时 它会使motionEvent ge
  • 绘制多个类别的 ROC 曲线

    我正在按照此链接绘制多个类别的 ROC 曲线的文档 http scikit learn org stable auto examples model selection plot roc html http scikit learn org
  • 如何在Chip Material组件中显示进度drawable动画?

    据官方称Action Chips 的设计文档 https material io design components chips html action chips 我们应该能够为芯片添加进度状态 可悲的是 开发文档 https mater
  • 如何返回正则表达式子匹配组,同时忽略空格?

    我正在寻找一些有关正则表达式的帮助 我拥有的数据是由逗号分隔的 5 个数字组成的组 那么 可能会有这样的数据 不带逗号的单个组 12345 任意数量的组 12345 54321 56789 09876 12345 54321 56789 或
  • 如果事件在 .NET 中作为委托实现,那么 .event IL 部分的意义何在?

    我在 Stack Overflow 上看到了一些非常好的问题 涉及委托 事件以及这两个功能的 NET 实现 特别提出一个问题 C 事件在幕后如何工作 https stackoverflow com questions 213638 how