Visual Basic, почему я не могу импортировать «System.Drawing», если моя единственная ссылка - «System»? - PullRequest
7 голосов
/ 19 января 2012

В Visual Studio 10 - Visual Basic, почему я не могу импортировать «System.Drawing», когда моя единственная ссылка - «Система»? Я могу импортировать "System.Runtime.InteropServices".

Чтобы воспроизвести мою проблему:
1. Создайте новый проект в Visual Studio 10 с помощью шаблона библиотеки классов Visual Basic.
2. В начале добавьте «Импортирует System.Drawing» и «Импортирует System.Runtime.InteropServices».
3. Удалите все ссылки, кроме «Система», на панели «Ссылки» свойств проекта.

Результат: Visual Studio не может найти «System.Drawing», но может найти «System.Runtime.InteropServices». «System.Drawing» полностью квалифицирован, поэтому система должна быть в состоянии найти его внутри указанной «System».

Мысли: Похоже, что «System» и «System.Drawing» являются отдельными пространствами имен (или контейнерами?), Так почему не подходит «» Работа? Делает "." представлять что-то еще?

«Система» также находится в «mscorlib», но это пространство имен, которое используется, или это другое?

«Microsoft.VisualBasic» также указан в импортированных пространствах имен, но на него нет ссылки. Как это было найдено? Откуда заполняется список «Импортированные пространства имен»?

Ссылка на любую связанную информацию из библиотеки MSDN определенно была бы полезной. Я просматривал это некоторое время, но не могу понять, почему «System.Drawing» не импортируется.

Ответы [ 4 ]

15 голосов
/ 19 января 2012

Инфраструктура общего языка .NET имеет две разные концепции:

  • Пространства имен: Префиксы для имен типов, таких как System.Drawing, которые используются для различения нескольких типов, которые могли быв противном случае имя будет одинаковым.
  • Сборки: Библиотеки кода, которые можно развертывать, устанавливать и создавать версии отдельно от других сборок.Типы в сборке могут быть в любом количестве пространств имен.

Пространства имен образуют иерархию, основанную на точечных разделителях - поэтому вы должны думать, что типы в пространстве имен System.Runtime.InteropServices подчинены типам в пространстве имен System.Runtime.Однако, насколько мне известно, CLI не заботится об имени или иерархии ваших пространств имен, за исключением того, что они делают ваши имена типов уникальными.

Кроме того, сборка может содержать типы из нескольких пространств имен, даже из разных иерархий, , а одно пространство имен может содержать типы, определенные в нескольких сборках. Если вы посмотрите документацию MSDN длявведите библиотеки .NET, и вы узнаете, в какой сборке находится этот тип. Однако, как указал Паоло Фалабелла, , MSDN не скажет, в какой сборке находится пространство имен, поскольку одно пространство имен можетсодержат типы из нескольких сборок.

В вашем сценарии: mscorlib - это сборка, которая определяет некоторые типы в пространстве имен System и многие другие, такие как System.Runtime.InteropServices, как вы заметили.Однако типы, которые вы используете в пространстве имен System.Drawing, находятся в сборке System.Drawing.

Поскольку сборки являются единицей развертывания и повторного использования кода, Visual Studio проектирует справочные сборки, а не пространства имен и т. Д.Вы должны добавить ссылку на сборку System.Drawing в проекте Visual Studio для своей программы.

Оператор VB.NET Imports (и его эквивалент C #, Директива using ) позволяет ссылаться на типы в пространстве имен без необходимости каждый раз вводить имя пространства имен.То есть, с Imports System.Drawing вы можете написать Graphics в своем коде вместо System.Drawing.Graphics.Но это all , что делает оператор Imports.В частности:

  • Imports System не создает автоматически ссылки на проекты для каждой сборки в мире, которая определяет типы в пространстве имен System.
  • Imports mscorlib не означает, что вы ссылаетесь на каждый тип в сборке "mscorlib" по его короткому имени.Это означает, что вы можете ссылаться на типы в пространстве имен «mscorlib» по их коротким именам, что не только совсем не так, но очень маловероятно, что вы хотите.

Итог:если вам нужен доступ к GDI +, то вы используете типы в пространстве имен System.Drawing, но это имя не имеет ничего общего с именем сборки GDI +.Microsoft выбрала имя «System.Drawing» для сборки, содержащей типы GDI +, но она могла бы выбрать «gdiplus-cli», «gdi-for-dotnet» или даже «Frobinator».Независимо от названия этой сборки, вы должны добавить ссылку на эту сборку.И вы не делаете этого в своем исходном коде - вы добавляете ссылки на сборки в вашей конфигурации проекта Visual Studio.

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

7 голосов
/ 19 января 2012

Пространство имен System.Drawing «живет» в другой dll, на которую изначально не ссылались в проекте шаблона для библиотеки классов.Вам нужно будет добавить ссылку на System.Drawing (щелкните правой кнопкой мыши по проекту -> добавить ссылку; System.Drawing находится в GAC).

На MSDN вы можете видеть, в какой сборке «живет» каждый класс.Например, в документации для класса Bitmap вы можете увидеть:

Пространство имен: System.Drawing

Assembly: System.Drawing (в System.Drawing.dll)

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

1 голос
/ 19 января 2012

System.Drawing находится в отдельной сборке, на которую нужно ссылаться.

0 голосов
/ 20 февраля 2014

Даже после добавления System.Drawing в качестве ссылки его все равно нельзя включить в проект.

...