C#编译器错误地优化代码

时间:2008-09-23 20:05:42

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

我有一个在远程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:此问题似乎是由Microsoft的ILMerge工具引入的。我们目前正在研究如何克服它。

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

  1. 关闭优化。

  2. 将装配与ILMerge合并到另一台机器上。

  3. 所以我们想知道构建机器是否在某种程度上错误配置(考虑到我们已经使用机器来构建版本超过一年,这很奇怪)或者是否存在其他问题。

6 个答案:

答案 0 :(得分:7)

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

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

您是否曾向微软提出错误?

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

答案 1 :(得分:1)

您确定您正在查看的程序集实际上是从相关源代码生成的吗?您是否可以使用小型测试用例重现此问题?

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

编辑2:嗯...我刚刚意识到它不能成为Reflector的错误,或者你不会在运行时收到错误信息。

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

我同意Curt和Beds;这听起来像是严重错误。优化器已经为我们所有人工作过,并且没有报告过这样的错误(我知道) - 实际上,你是否做错了?

旁注:我还想指出{。{1}}在.Net fx 3.5中,并且完全属于System.Collections.Generic.HashSet<T>类。

答案 4 :(得分:0)

最近是否将代码部署到该服务器?有人在你不知情的情况下推动了构建吗?你可以进行源代码控制,提取最新信息并复制问题吗?

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

答案 5 :(得分:0)

哎哟。如果这确实是错误的ILMerge,请保持这个主题与您的发现保持同步 - 我使用ILMerge作为构建COM互操作程序集的关键步骤。