【问题标题】:Why does the compiler remove unused structs but not classes为什么编译器会删除未使用的结构而不是类
【发布时间】:2016-07-24 13:40:01
【问题描述】:

我有闲置代码

static void Main(string[] args)
{
    var str = new DummyStruct();
    var testClass = new DummyClass();
}

类或结构都没有任何实现。但是当我在使用 ILSpy 构建发布后查看代码时,我得到了

private static void Main(string[] args)
{
    new DummyClass();
}

所以我的问题是:为什么编译器会忽略结构的实例化而不是类的实例化?

【问题讨论】:

  • C# 编译器对于删除死代码非常保守。这是抖动的工作,它对代码的实际作用有更多的了解。但是对于结构的“默认构造函数”来说,这非常容易,C# 和 CLR 都不允许定义一个。必须写“新”本身是没有用的,但受到 C# 中明确分配规则的启发。例如,在 VB.NET 或 C++/CLI 中不需要。
  • @HansPassant 这是一个非常有用的评论。但经过一番研究,我发现只是 C# 不允许创建无参数构造函数,从 CLR 的角度来看,它似乎完全没问题。您是否有任何文件显示相反的情况?
  • Ecma-335 第 II.13.2 章,理由括号。
  • @HansPassant 我读过完全相同的段落,但它描述了 CLR 执行此操作的方式,它没有指定您无法创建默认构造函数的任何地方,例如 C# 规范确实具体在 11.13.8

标签: c# .net compilation compiler-optimization


【解决方案1】:

var str = new DummyStruct();,当str 随后未被使用时,不做任何事情。特别是,不会调用 DummyStruct 的构造函数。

var testClass = new DummyClass();,当testClass 随后未被使用时,它可能会做一些事情。 DummyClass 的构造函数可能有副作用。即使它目前在编译器看来没有副作用,但如果它驻留在不同的程序集中,如果使用不同版本的库,它在运行时可能会产生副作用。

【讨论】:

  • 那么创建结构体有没有办法产生副作用?我最初考虑的是静态构造函数,但它们对结构的工作方式与我所看到的不同。
  • @toby 带参数的struct 构造函数可能有副作用,但C# 甚至不允许您创建无参数的struct 构造函数,编译器将任何new Struct() 视为@987654330 @.
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 2011-03-11
  • 2023-04-01
  • 2014-08-05
相关资源
最近更新 更多