我有一个 ASP.NET 应用程序在远程 Web 服务器上运行,但我刚刚开始收到此错误:
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: 到目前为止,我们找到了两种方法来解决这个问题。 我们不太明白根本问题是什么,但这两个都解决了它:
关闭优化。
在另一台机器上将程序集与 ILMerge 合并。
因此我们想知道构建机器是否配置错误(考虑到我们已经使用该机器构建版本一年多了,这很奇怪)或者是否是其他问题。
啊,ILMerge - 您问题中的额外信息确实有助于解决您的问题。虽然我不会期望 .net 编译器会以这种方式失败,但我希望 ILMerge 偶尔会看到这种情况(考虑到它正在做什么)。
我的猜测是,您的两个程序集使用相同的优化“技巧”,一旦合并,就会出现冲突。
您向 Microsoft 提出了该错误吗?
同时的解决方法是将源代码中的程序集重新编译为单个程序集,从而无需使用 ILMerge。 由于 csproj 文件只是 XML 列表,因此它们基本上很容易合并,并且您可以将其自动化作为额外的 MSBuild 步骤。
您确定您正在查看的程序集实际上是从相关源代码生成的吗? 你能用一个小测试用例重现这个问题吗?
编辑:如果您使用 Reflector,MSIL 到 C# 的转换可能不正确 - Reflector 在反编译时并不总是 100% 准确。 MSIL 是什么样的?
编辑 2: 嗯...我刚刚意识到这不可能是 Reflector 的错误,否则你不会在运行时收到该错误消息。
这更有可能是反射工具的问题,而不是 .Net 编译的问题。您收到的错误 - 在远程处理期间未找到构造函数很可能是序列化问题(所有可序列化类都需要无参数构造函数)。
从反射工具找到的代码更有可能抛出类型转换异常。
我同意 Curt 和 Beds 的观点;这听起来好像有什么严重错误。优化器对我们所有人都有效,并且没有报告此类错误(据我所知) - 难道您实际上做错了什么?
旁注:我还想指出
System.Collections.Generic.HashSet<T>
位于 .Net fx 3.5 中,它的作用正是 Set<>
类应该做的。
最近是否将代码部署到该服务器?有人会在您不知情的情况下推送构建吗?您可以转到源代码管理,提取最新版本并复制该问题吗?
此时,根据给定的信息,我怀疑是编译器的问题。
哎呀。如果这确实是 ILMerge 的错误,请根据您的发现及时更新本主题 - 我使用 ILMerge 作为构建 COM 互操作程序集的关键步骤。