调用非赋值类的方法

2023-12-10

我对这两方面都有疑问;

第一;

        Test test = new Test();

        result = test.DoWork(_param);

第二个;

       result = new Test().DoWork(_param);

如果我们不将新创建的实例分配给变量并直接调用方法会发生什么?

我发现两种 IL 代码之间存在一些差异。


下面是第一个 C# 代码的 IL 输出

 IL_0000:  ldstr      "job "
 IL_0005:  stloc.0
 IL_0006:  newobj     instance void Works.Test::.ctor()
 IL_000b:  stloc.1
 IL_000c:  ldloc.1
 IL_000d:  ldloc.0
 IL_000e:  callvirt   instance string Works.Test::DoWork(string)
 IL_0013:  pop
 IL_0014:  ret

这是第二个c#代码的IL输出

 IL_0000:  ldstr      "job "
 IL_0005:  stloc.0
 IL_0006:  newobj     instance void Works.Test::.ctor()
 IL_000b:  ldloc.0
 IL_000c:  call       instance string Works.Test::DoWork(string)
 IL_0011:  pop
 IL_0012:  ret

您能告诉我一下吗?


这个问题在这里有点难找到,但我认为你要问的是:

为什么将新创建的引用分配给变量会导致编译器生成callvirt,但直接调用方法会生成call?

你非常善于观察,注意到了这种微妙的差异。

在回答您的问题之前,让我们先回答一些其他问题。

我应该相信编译器会生成好的代码吗?

一般来说是的。偶尔会出现代码生成错误,但这不是其中之一。

用callvirt调用非虚方法合法吗?

Yes.

用call调用虚方法合法吗?

是的,如果您尝试调用基类方法而不是派生类中的重写。但通常这种情况不会发生。

本例中调用的方法是否是虚拟的?

这不是虚拟的。

由于该方法不是虚拟的,因此可以使用 callvirt 或 call 来调用它。为什么编译器有时生成 callvirt,有时生成 call,而它可以一致地两次生成 callvirt 或调用两次?

现在我们来谈谈你问题中有趣的部分。

call 和 callvirt 之间有两个区别。

  • call 不做虚拟调度; callvirt 在调用之前会在虚函数调度表中查找正确的方法。因此 callvirt 大约慢一纳秒。

  • 卡尔维特总是检查接收者是否为空,无论调用的方法是否为虚拟方法。调用不会检查接收者是否为空。通过 call 调用带有 null“this”的方法是合法的。

现在也许你明白这是怎么回事了。

每当对空引用接收器进行调用时,C# 是否需要因空取消引用异常而崩溃?

Yes。 C# 是required当您使用空接收器调用某些内容时会崩溃。因此,C# 在生成调用方法的代码时有以下选择:

  • 情况 1:生成检查 null 的 IL,然后生成调用。
  • 情况2:生成callvirt。
  • 情况 3:生成调用,但不以空检查开始。

案例1简直就是愚蠢的。 IL 更大,因此占用更多磁盘空间,加载速度更慢,抖动速度也更慢。当 callvirt 自动执行空检查时生成此代码是愚蠢的。

案例2很聪明。 C# 编译器生成 callvirts,以便自动完成 null 检查。

现在案例 3 怎么样?什么情况下C#可以跳过空检查并生成调用?只有当:

  • 该调用是非虚拟方法调用,并且
  • C# 已经知道接收者不为空

但 C# 知道在new Foo().Bar()接收者不能为空,因为如果是的话,构造就会抛出异常,并且我们永远不会调用!

编译器是not足够聪明,能够意识到该变量只被分配过非空值。所以它会生成一个 callvirt 以保证安全。

编译器could被写得那么聪明。编译器已经必须跟踪变量的赋值状态以进行明确的赋值检查。它还可以跟踪“被分配了可能为空的东西”状态,然后它会在这两种情况下生成调用。但编译器(还)还没有那么聪明。

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

调用非赋值类的方法 的相关文章

  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • C# 中可空类型是什么?

    当我们必须使用nullable输入 C net 任何人都可以举例说明 可空类型 何时使用可空类型 https web archive org web http broadcast oreilly com 2010 11 understand
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 网络参考共享类

    我用 Java 编写了一些 SOAP Web 服务 在 JBoss 5 1 上运行 其中两个共享一个类 AddressTO Web 服务在我的 ApplycationServer 上正确部署 一切都很顺利 直到我尝试在我的 C 客户端中使用
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • Bing 地图运行时错误 Windows 8.1

    当我运行带有 Bing Map 集成的 Windows 8 1 应用程序时 出现以下错误 Windows UI Xaml Markup XamlParseException 类型的异常 发生在 DistanceApp exe 中 但未在用户
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐

  • 通过代码隐藏中的按钮单击处理程序中的 ID 访问 DataList 中的 TextBox

    我有一个文本框 保存在数据列表中 我需要通过 ID 找到它 以便我可以将写入该文本框的文本插入到数据库中 这是我的包含文本框的 aspx 页面
  • Microsoft 日志记录应用程序块和多线程

    我是日志应用程序块 4 1 的新手 有人编写过从多个线程使用日志记录应用程序块的应用程序吗 我问这个问题是因为 Logger 是一个静态类 并且可能会从多个线程写入同一日志文件 日志应用程序块是线程安全的 这意味着您可以从多个线程调用其公共
  • cURL 无法在本地服务器中使用客户端证书

    我使用 XAMPP 设置了本地服务器 我有两个 PHP 脚本 一个发送者和一个接收者 我正在尝试使用 HTTP over SSL HTTPS 将 XML 文件从发送方发送到接收方 我创建了一个自签名证书 配置了 XAMPP 并且我在发件人上
  • @solana/web3.js 有 ERC721 元数据的 API 吗?

    给定一个代币铸造地址 我正在寻找一种方法来访问 ERC721 代币的元数据 solana web3 js 中有 API 吗 Solana 将代币元数据存储在从原始代币地址派生的地址中https docs solana com develop
  • 通过动态属性从对象数组创建对象

    我有一个对象数组 options width 10 height 20 width 20 height 40 width 30 height 60 我想转换为以下内容 width 10 20 30 height 20 40 60 现在请记住
  • SqlDataAdapter.update() 不更新数据库

    我正在使用 PostLikes 表搜索 PostId UserId SqlDataAdapter 如果找到该行 我正在使用SqlCommandBuilder GetDeleteCommand 生成删除指令并删除底层行 如果找不到该行 那么我
  • 以编程方式将模块/函数集转换为 Python 类

    假设我有一个包含一堆方法的文件 如 chunk methods py def one x return int x def two y return str y 有没有办法通过导入模块整体或选择方法来获取该组方法 并将导入的方法转换为类 例
  • UIApplicationBackgroundRefreshStatusDidChangeNotification 使用没有相应的委托方法

    我觉得UIApplicationBackgroundRefreshStatusDidChangeNotificationiOS 7 中引入的如果不支持 UIApplication 委托方法就没有什么用处 因为 当用户打开我的应用程序的后台刷
  • UWP/C# - AQS 和 USB 设备问题

    我尝试编写的 UWP 应用程序出现问题 我正在连接到我已编程的自定义嵌入式 USB 批量设备 它实际上是 Cypress Semiconductor 的开箱即用示例 我正在使用 WinUSB sys 驱动程序 该驱动程序使用设备中嵌入的 M
  • MySQL:“where 子句中的列‘column_name’不明确”

    我加入 2 个表 例如 table A user id ticket id user name table B ticket id ticket name 如果我运行以下查询 SELECT table A user id table A u
  • 游戏的 3D 模型格式

    我四处寻找可以在我正在构建的游戏中使用的良好模型格式 它是一款可在任何平台上运行的单人角色扮演游戏 我查看了 md2 3 和 5 种格式 obj 和 3ds 但我找不到我想要的东西 我所需要的只是一个带有动画的 3D 模型 我可以将纹理应用
  • Powershell 为什么两个json内容有区别?

    我有两个变量Byte type 我选择此类型是为了满足特定需求 因此需要保留它 声明为 first New Object Byte 32 second New Object Byte 32 并且 我初始化了两个变量的每个索引 现在 我创建了
  • 如何将十六进制字符串转换为int数组

    我有十六进制字符串 例如 01ff6fee32785e366f710df10cc542B4 我正在尝试将它们 有效地 转换为 2 个字符乘 2 个字符的 int 数组 例如 1 255 I tried c 8db6796fee32785e3
  • 验证 JWT 令牌 C# 的签名

    我在验证我获得的 JWT 令牌的签名时遇到一些问题 该令牌使用 HS256 进行签名 我尝试创建签名以证明收到的签名的代码是 JwtSecurityToken token tokenHandler ReadJwtToken tokenStr
  • 获取在 Instagram 上喜欢特定媒体的用户列表

    使用 Instagram API 我需要获取喜欢特定媒体的用户列表 根据文档 以下调用应返回所有用户的列表 https api instagram com v1 media 555 likes access token ACCESS TOK
  • onSaveInstanceState 没有被调用

    我有一项活动 它启动结果代码的各种活动并获取结果onActivityResult方法它根据结果代码启动适当的活动 onSaveInstanceState没有在为结果而启动的活动中被调用 例如 导航活动将活动 A 启动为 Intent int
  • 从 JavaScript 访问 Prestashop Web 服务

    在 Prestashop 后端 我激活了 Web 服务并创建了一个身份验证密钥 在浏览器中进行测试效果很好 但现在我想在 Cordova 应用程序中通过 JavaScript 访问 Web 服务 我得到的回应是401 Unauthorize
  • 可滚动 ListView 将背景颜色渗透到相邻的小部件

    我希望使用可滚动的 ListView 和不可移动的标题图块创建一个简单的布局 我已将标题图块和 ListView 放入列中 因此标题可以位于 ListView 上方 而无需滚动到屏幕之外 但是 当滚动 ListView 时 我的标题图块似乎
  • 使用 webpack-dev-server 启动时,Docker 容器未按预期发布端口

    我有一个简单的 Dockerfile 来创建一个图像来充当我的节点应用程序的开发环境 问题是容器和我的机器之间的端口绑定无法按预期工作 Dockerfile FROM node 10 12 0 EXPOSE 8080 我使用以下命令从该文件
  • 调用非赋值类的方法

    我对这两方面都有疑问 第一 Test test new Test result test DoWork param 第二个 result new Test DoWork param 如果我们不将新创建的实例分配给变量并直接调用方法会发生什么