2009-03-07 2 views
12

Я прочитал, что удаление неиспользуемых ссылок makes no difference компилятору, поскольку оно игнорирует сборки, на которые не ссылаются сам код.Какова цель «удалить неиспользуемые ссылки»

Но мне трудно поверить, потому что тогда, какова реальная цель Removing unused references? Он не оказывает заметного влияния на размер сгенерированной сборки или иным образом. Или это smart поведение, ограниченное компилятором C# (csc.exe) и не присущим vbc.exe?

Если эта функциональность настолько бесполезна, почему ReSharper предлагает ее как функцию? Почему это предусмотрено в диалоговом окне «Конфигурация проекта Visual Studio»?

Единственное, что я могу придумать, где это было бы полезно, - это во время развертывания. Ссылки (используемые или неиспользуемые) все равно будут скопированы установщиком. Но для сборок, которые находятся в GAC (например, сборки BCL), это тоже не проблема.

ответ

14

Это не позволяет CLR загружать указанный модуль во время выполнения. Это сократит время запуска (поскольку для загрузки каждого модуля требуется время). В зависимости от размера модуля он может заметно уменьшить время запуска.

Один из способов протестировать это, чтобы создать тестовый проект WinForms, добавить ссылку на сборку, которая не используется (например, System.Web), затем запустить и прикрепить к исполняемому файлу (например, F5). Просмотрите загруженные модули (Debug -> Windows -> Modules), и вы увидите, что загруженная ссылка была загружена.

Если вы думаете об этом, CLR будет довольно сложно определить, действительно ли зависимость (она в манифесте как зависимость после добавления ссылки на нее) действительно используется ... Тем более, что выполнение некоторых путей кода не может быть заранее известно ...

+1

Как CLR собирается загрузить модуль во время выполнения, ссылка которого была удалена оптимизацией компилятора? Что мне здесь не хватает? – Dan

+0

@ Dan - Я также не понимаю, почему в этом ответе было так много upvotes, из того, что я читал на других постах, компилятор не будет помещать ссылку на сборку в окончательный вывод, если он не используется. Связанные сборки будут загружаться только JIT при первом вызове метода. Окно загруженных модулей, которое этот ответ дает в качестве доказательства, может отображать все ссылки, поскольку он находится в режиме отладки. – BornToCode

+0

@BornToCode Кроме того, если 'it [is] трудно для CLR определить, действительно ли используется зависимость, то как вообще работает« Удалить неиспользуемые ссылки »? Определение того, используется ли эта ссылка, просто: если ни один код не ссылается ни на что в пространстве имен этой сборки, он не используется. – Dan

12

Помимо исходных файлов, которые меньше, я думаю, что лучше иметь чистый исходный файл, у которого нет неиспользованного кода или ссылок.

+0

Спасибо, Кристоф, но вопрос остается ... как/почему это лучше? – Cerebrus

+2

Лучше, потому что ваши исходные файлы не будут раздуты, это будет неиспользованный код/​​импорт и, следовательно, будет легче читать и понимать. Кроме того, я думаю, что у компилятора будет меньше работы, и компиляция будет немного быстрее. (Я не уверен на 100%, и это специфично для компилятора) –

8

Visual Studio 2008 также имеет функцию удаления неиспользуемых директив.

Извлечение неиспользуемого кода делает код более аккуратным, но вы также можете уменьшить риск конфликтов. Иногда в разных сборках есть классы с одинаковым именем. Например, существует класс Image как в System.Drawing, так и System.Web.UI.WebControls. Если вы используете директивы для обоих пространств имен и начинаете использовать класс Image, компилятор не может определить, какие из них использовать.

+0

+1: уменьшить риск конфликтов – Sung

6

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

Компилятор C# достаточно умен, чтобы испускать только ссылки на сборку в метаданных вашей сборной сборки для фактически используемых сборок. Таким образом, вы не будете генерировать собственные изображения для сборок, которые вы не используете при запуске Ngen.exe. Компилятор JIT не будет затронут в любом случае, он загружает сборку только по мере необходимости, чтобы перевести IL.

+0

Означает ли это, что при загрузке сборки NGENed все ссылочные сборки также загружаются впоследствии? Или, другими словами: ленивая загрузка родных сборок невозможна? По крайней мере, это то, что я вижу, когда сравниваю загруженные сборки моего приложения (JITed vs. NGENed). – Yves

 Смежные вопросы

  • Нет связанных вопросов^_^