Вопрос

У меня есть приложение 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 на другом компьютере.

Поэтому нам остается задаться вопросом, неправильно ли настроена машина сборки (что странно, учитывая, что мы используем машину для сборки релизов уже больше года) или это какая-то другая проблема.

Это было полезно?

Решение

Ааа, ILMerge - эта дополнительная информация в вашем вопросе действительно помогает решить вашу проблему.Хотя я никогда не ожидал, что компилятор .net выйдет из строя таким образом, я ожидаю время от времени видеть подобные вещи с ILMerge (учитывая, что он делает).

Я предполагаю, что две ваши сборки используют один и тот же «трюк» оптимизации, и после слияния вы получаете конфликт.

Вы сообщили об ошибке в Microsoft?

Тем временем обходным путем является перекомпиляция сборок из исходного кода как одна сборка, что избавляет от необходимости использовать ILMerge.Поскольку файлы csproj представляют собой просто списки XML, их в основном легко объединить, и вы можете автоматизировать это в качестве дополнительного шага MSBuild.

Другие советы

Вы уверены, что рассматриваемая вами сборка действительно была создана на основе рассматриваемого исходного кода?Сможете ли вы воспроизвести эту проблему с помощью небольшого тестового примера?

Редактировать: если вы используете Reflector, возможно, преобразование MSIL в C# неверно — Reflector не всегда обеспечивает 100% точность декомпиляции.Как выглядит MSIL?

Редактировать 2: Хм...Я только что понял, что это не может быть вина Reflector, иначе вы бы не получили это сообщение об ошибке во время выполнения.

Скорее всего, это проблема с инструментом отражения, чем с компиляцией .Net.Ошибка, которую вы получаете: конструктор, не найденный во время удаленного взаимодействия, скорее всего, является проблемой сериализации (все сериализуемые классы нуждаются в конструкторе без параметров).

Код, найденный с помощью вашего инструмента отражения, с большей вероятностью вызовет исключение приведения типов.

Я согласен и с Куртом, и с Бедсом;это звучит так, будто что-то серьезно не так.Оптимизатор работал у всех нас, и о таких ошибках не сообщалось (насколько мне известно) - может быть, вы действительно делаете что-то не так?

Примечание:Я также хотел бы отметить System.Collections.Generic.HashSet<T> который находится в .Net fx 3.5 и делает именно то, что Set<> класс должен.

Был ли код недавно развернут на этом сервере?Мог ли кто-то запустить сборку без вашего ведома?Можете ли вы пойти в систему контроля версий, получить последнюю версию и продублировать проблему?

На данный момент, учитывая предоставленную информацию, я сомневаюсь, что дело в компиляторе.

Ой.Если это действительно ошибка ILMerge, пожалуйста, держите эту тему в курсе своих выводов — я использую ILMerge как ключевой шаг в построении сборки COM-взаимодействия.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top