【问题标题】:C# Compiler Incorrectly Optimizes CodeC# 编译器错误地优化代码
【发布时间】:2008-09-23 20:05:41
【问题描述】:

我有一个在远程 Web 服务器上运行的 ASP.NET 应用程序,但我刚刚开始收到此错误:

Method not found: 'Void System.Collections.Generic.ICollection`1..ctor()'.

我反汇编了 DLL 中的代码,编译器似乎错误地优化了代码。 (请注意,Set 是一个实现一组唯一对象的类。它继承自 IEnumerable。)这一行:

Set<int> set = new Set<int>();

编译成这一行:

Set<int> set = (Set<int>) new ICollection<CalendarModule>();

CalendarModule 类是一个完全不相关的类!!以前有没有人注意到 .NET 错误地编译这样的代码?

更新#1: 这个问题似乎是由微软的ILMerge 工具引入的。我们目前正在研究如何克服它。

更新 #2: 到目前为止,我们找到了两种解决此问题的方法。我们不太了解潜在的问题是什么,但是这两个都解决了它:

  1. 关闭优化。

  2. 在不同的机器上使用 ILMerge 合并程序集。

所以我们想知道构建机器是否以某种方式配置错误(考虑到我们已经使用该机器构建版本已经一年多了,这很奇怪)还是其他问题。

【问题讨论】:

  • 这不足以调试您的问题。你能上传足够多的代码来在某处重现问题吗?
  • 你不知道 Int 继承自 CalenderModule 吗? :)

标签: c# asp.net optimization compiler-construction ilmerge


【解决方案1】:

啊,ILMerge - 您问题中的额外信息确实有助于解决您的问题。虽然我从没想过 .net 编译器会以这种方式失败,但我希望偶尔会在 ILMerge 中看到这种事情(考虑到它在做什么)。

我的猜测是您的两个程序集使用相同的优化“技巧”,一旦合并就会发生冲突。

您是否向 Microsoft 提出了该错误?

与此同时,一种解决方法是从源代码将程序集重新编译为单个程序集,从而节省对 ILMerge 的需求。由于 csproj 文件只是 XML 列表,因此它们基本上很容易合并,您可以将其作为额外的 MSBuild 步骤自动化。

【讨论】:

  • 有没有人有关于如何在没有 ILMerge 的情况下使用 cs/vb 编译器将多个程序集编译为一个的好资源?
  • @Lamar:我之前已经回答过这个问题。见stackoverflow.com/questions/1878807/…
【解决方案2】:

您确定您正在查看的程序集实际上是从相关源代码生成的吗?你能用一个小测试用例重现这个问题吗?

编辑:如果您使用 Reflector,则 MSIL 到 C# 的转换可能不正确——Reflector 在反编译时并不总是 100% 准确。 MSIL 是什么样的?

编辑 2: 嗯...我刚刚意识到它不可能是 Reflector 的错误,否则您在运行时不会收到该错误消息。

【讨论】:

  • 到目前为止,我无法用较小的测试用例重现该问题。在这种情况下,反汇编似乎是正确的。我引用 ICollection 构造函数的错误证明了这一点。
【解决方案3】:

这更可能是反射工具的问题,而不是 .Net 编译的问题。您遇到的错误 - 在远程处理期间未找到构造函数很可能是序列化问题(所有可序列化类都需要无参数构造函数)。

从您的反射工具中找到的代码更有可能引发类型转换异常。

【讨论】:

  • 好的,但是抛出异常需要以下代码:new ICollection()
【解决方案4】:

我同意 Curt 和 Beds 的观点;这听起来像是严重错误。优化器对我们所有人都有效,并且没有报告过这样的错误(据我所知) - 实际上是不是您做错了什么?

旁注:我还想指出System.Collections.Generic.HashSet&lt;T&gt;,它位于.Net fx 3.5 中,并且完全符合Set&lt;&gt; 类的功能。

【讨论】:

  • 我绝对同意“选择没有被破坏”的思想流派,并且该错误实际上可能不是由错误的编译器引起的,只是让它看起来像是糟糕的优化。感谢关于 HashSet 的提示,不幸的是我们还没有使用 3.5,仍然使用 2.0。
【解决方案5】:

最近是否将代码部署到该服务器?有人会在您不知情的情况下推动构建吗?你能去源代码控制,拉出最新的,然后复制问题吗?

此时,根据给定的信息,我怀疑它是编译器。

【讨论】:

    【解决方案6】:

    哎哟。如果这确实是 ILMerge 的问题,请根据您的发现及时更新本主题——我使用 ILMerge 作为构建 COM 互操作程序集的关键步骤。

    【讨论】:

    • 我会告诉你我们发现了什么。
    猜你喜欢
    • 2013-03-11
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多