【问题标题】:Why does debug build result in one more variable?为什么调试构建会导致多一个变量?
【发布时间】:2019-06-27 07:56:05
【问题描述】:

这是代码:

Employee e = new Employee() { Name = "Jeff", Age = 45 };

这是构建调试程序集时的编译方式:

Employee employee = new Employee();
employee.Name = "Jeff";
employee.Age = 45;
Employee employee2 = employee;

这就是它在构建版本时的编译方式:

Employee employee = new Employee();
employee.Name = "Jeff";
employee.Age = 45;

问题是:为什么调试构建会产生一个引用同一对象的变量?

【问题讨论】:

  • “如何编译”是什么意思?您是否有一个新变量突然出现在生成的二进制文件中?
  • @someone sharplab.io/…

标签: c# .net build compilation debug-build


【解决方案1】:

SharpLab 正在获取已编译的 IL 并尝试将其转换回可读的 C#,生成的 C# 并不总是与最初编译的代码完全匹配。

如果我们查看生成的 IL,在 Debug 模式下我们会得到以下信息(我删除了一些 nop(no-op)指令以保持整洁:

.locals init (
    [0] class Employee
)

IL_0001: newobj instance void Employee::.ctor()
IL_0006: dup
IL_0007: ldstr "Jeff"
IL_000c: callvirt instance void Employee::set_Name(string)
IL_0012: dup
IL_0013: ldc.i4.s 45
IL_0015: callvirt instance void Employee::set_Age(int32)
IL_001b: stloc.0
IL_001c: ret

在发布时,几乎完全相同:

IL_0000: newobj instance void Employee::.ctor()
IL_0005: dup
IL_0006: ldstr "Jeff"
IL_000b: callvirt instance void Employee::set_Name(string)
IL_0010: dup
IL_0011: ldc.i4.s 45
IL_0013: callvirt instance void Employee::set_Age(int32)
IL_0018: pop
IL_0019: ret

唯一真正的区别是 Debug 版本为 employee 分配一个局部变量,而 Release 版本没有,因为它从未使用过,因此不需要。

正如我们所见,您在 Debug 版本中看到的“额外”变量并不真正存在,这只是 SharpLab 尝试将编译后的 IL 转换回可读 C# 的产物,实际上 Release 版本已经“丢失" 一个局部变量,因为它不是必需的。

【讨论】:

  • 更具体地说,调试构建将变量的生命周期延长到作用域的末尾,因此可以使用调试器轻松检查它们
【解决方案2】:

我猜你应该像这样创建你的第二个对象。

Employee employee2 = new Employee();

然后

employee2= employee;

【讨论】:

  • 等等,为什么?...问题不在于它,上面的代码没问题。
猜你喜欢
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 2019-10-23
相关资源
最近更新 更多