black.Paint(); PaintColor.StaticPaint();
Директива using говорит компилятору: "Если ты не в состоянии найти определен ный класс в текущем пространстве имен, посмотри еще и в этом пространстве имен, мо жет, ты найдешь его там". Можно указать любое количество пространств имен, но все они должны быть указаны в самом начале программы (либо внутри, либо снаружи блока пространства имен), как описано ранее в разделе "Объявление пространств имен".
Все программы включают директиву using System,-. Эта команда дает программе автоматический доступ к функциям, включенным в системную библиотеку, таким как WriteLine ().
Использование полностью квалифицированных имен
Приведенная далее демонстрационная программа NamespaceUse иллюст рирует влияние пространств имен на видимость и использование директивы using и полностью квалифицированных имен, чтобы обеспечить види мость элемента.
//NamespaceUse - демонстрирует доступ к объектам с одним и
//тем же именем в разных пространствах имен
using System; // Все пространства имен нуждаются в этой
//директиве для доступа к классам типа String
//и Console
namespace MainCode
{
using LibraryCodel; // Эта директива упрощает MainCode public class Classl
{
public void AMethod()
{
Console.WriteLine("MainCode.Classl.AMethod() ") ;
}
// Функция Main():
static void Main(string[] args)
//Создание экземпляра класса, содержащего функцию
//Main, в данном пространстве имен
Classl cl = new C l a s s l О ; |
// MainCode.Classl |
cl.AMethod(); |
// |
Никогда |
не вызывайте |
|
// |
Main() |
самостоятельно! |
//Создание экземпляра LibraryCodel.Classl
//Приведенный далее код создает объект
// |
MainCode.Classl, |
а не тот, |
что вы хотели, так как |
// |
нет ни директивы |
using, ни |
полностью |
//квалифицированного имени Classl с2 = new Classl(),• с2.AMethod();
//Однако полностью квалифицированное имя создает
//объект требуемого класса. Имя следует
Глава 19. Работа с файлами и библиотеками |
427 |
//квалифицировать даже при использовании директивы
//using, поскольку оба пространства имен содержат
//класс Classl
LibraryCodel.Classl сЗ = new LibraryCodel.Classl(); c3 .AMethod () ,-
//В то же время создание LibraryCodel.Class2 не
//требует полностью квалифицированного имени,
//поскольку имеется директива using при отсутствии
//коллизии имен; С# может без труда найти Class2 Class2 с4 = new Class2();
с4.AMethod();
//Создание экземпляра LibraryCode2.Classl требует
//полностью квалифицированного имени, как из-за
//отсутствия директивы using для LibraryCode2, так и
//потому, что оба пространства имен имеют Classl
//Примечание: этот способ работает даже несмотря на
//то, что LibraryCode2.Classl объявлен как internal,
// |
а не public, |
поскольку оба класса |
находятся |
в одной |
// |
компилируемой |
сборке |
|
|
|
LibraryCode2.Classl с5 = new LibraryCode2.Classl(); |
с5.AMethod(); |
|
|
|
|
// |
Ожидаем подтверждения пользователя |
|
Console.WriteLine("Нажмите <Enter> для " + |
|
|
|
"завершения программы..."); |
|
Console.Read(); |
|
|
|
|
} |
|
|
|
|
|
namespace |
LibraryCodel |
|
|
|
|
{ |
|
|
|
|
|
public |
class Classl |
// |
Имя дублирует |
Classl в |
другом |
{ |
|
// |
пространстве |
имен |
|
public void AMethod() // |
Имя дублировано в другом |
{ |
|
// |
пространстве |
имен |
|
Console.WriteLine("LibraryCodel.Classl.AMethod()");
} } |
|
|
public class Class2 |
// |
Имя уникально, его нет в другом |
{ |
// |
пространстве имен |
public void AMethod()
{
Console.WriteLine("LibraryCodel.Class2.AMethod()");
namespace |
LibraryCode2 |
|
|
{ |
|
|
|
class Classl |
// |
Нет ключевых слов, описывающих |
{ |
|
// доступ: по умолчанию доступ — |
public |
void AMethod() |
// |
internal |
{
Console.WriteLine("LibraryCode2.Classl.AMethod()");
}
428 |
Часть VII. Дополнительные главы |
Данная демонстрационная программа включает три пространства имен: MainCode, в которое входит один класс Classl, содержащий функцию Main() и один дополни тельный метод AMethod ( ) . Пространство имен LibraryCodel содержит два класса: Classl дублирует имя Classl из пространства имен MainCode, класс Class2 уни кален. Пространство имен LibraryCode2 имеет один класс, также названный Classl, имя которого создавало бы коллизию с именем Classl в другом пространстве имен, ес ли бы эти имена не были разделены и размещены каждое в своем пространстве имен. Каждый их этих классов имеет метод AMethod ().
Функция Main () из MainCode . Classl пытается создать и использовать MainCode. Classl (класс-владелец MainO), LibraryCodel. Classl, Library Codel .Class2 и LibraryCode2 .Classl. После создания объектов функция вызы вает метод AMethod () каждого из них. Каждый метод идентифицирует свое местопо ложение. Вывод демонстрационной программы на экран выглядит следующим образом:
MainCode.Classl.AMethod()
MainCode.Classl.AMethod()
LibraryCodel.Classl.AMethod()
LibraryCodel.Class2.AMethod()
LibraryCode2.Classl.AMethod()
Нажмите <Enter> для завершения программы...
Без разделения на различные пространства имен компилятор не может позволить дублирования имен классов в MainO . При применении пространств имен исходный текст компилируется, но вы должны использовать либо директиву using, либо полно стью квалифицированные имена для обращения к объектам в разных пространствах имен. Пространство имен MainCode содержит директиву using для пространства имен
LibraryCodel, так что функция Main O из MainCode. Classl может обратиться к LibraryCodel. Class2 без полностью квалифицированного имени благодаря нали чию упомянутой директивы.
Попытка создать LibraryCodel. Classl без использования полностью квалифи цированного имени приводит ко второй строке в выводе на экран в рассмотренном при мере. Как видите, оказался создан объект класса MainCode. Classl, а не класса из пространства имен LibraryCodel. Без применения полностью квалифицированного имени компилятор находит Classl в пространстве имен MainCode. Остальные вызовы работают так, как от них и ожидалось.
Однако использование директивы using для пространства имен LibraryCodel сослужит функции Main () плохую службу при ее желании обратиться к Library Codel . Classl, так как имя этого класса дублировано в двух пространствах имен. Не смотря на наличие директивы using, единственным решением является применение полностью квалифицированного имени для доступа к LibraryCodel. Classl.
Последний вызов в Main () для создания и использования объекта Library2 . Classl был бы неверен, если бы пространство имен Library2 находилось в сборке, отличной от сборки MainCode. Причина заключается в том, что спе цификаторы доступа у класса Library2 .Classl не указаны, так что вместо того чтобы быть public, он является internal. Это поведение по умолча нию для классов без спецификаторов доступа (для методов по умолчанию ис пользуется private). Повторяясь еще р а з — всегда явно указывайте уровень доступа к каждому классу и методу.
Глава 19. Работа с файлами и библиотеками |
429 |
После того как вы используете полностью квалифицированные имена или директивы using, ваш класс сможет обратиться к чему угодно в другом пространстве имен, если конечно, это не запрещено ему правилами доступа — как, например, к закрытым членам.
В главе 21, "Использование интерфейса Visual Studio", вы познакомитесь с тем, как создавать проект с несколькими . СS-файлами. Даже при разбиении проекта на несколь ко файлов (обычно по одному классу в файле) один проект равен одной скомпилированной сборке. Библиотеки классов располагаются в файлах с расширением . DLL и не яв ляются выполнимыми программами сами по себе. Они служат для поддержки других программ, предоставляя им полезные классы и методы.
Простейшее определение проекта библиотеки классов — это классы, не содер жащие функции Main ( ) , что отличает библиотеку классов от выполнимой программы.
Visual Studio 2005 позволяет построить либо . ЕХЕ, либо . DLL (либо решение, со держащее их оба). В следующем разделе поясняются основы создания ваших собствен ных библиотек классов. Не беспокойтесь: рабочая лошадка С# вытянет за вас и этот груз.
Менее дорогие версии Visual Studio 2005, такие как Visual С# Express, не позволяют собирать библиотеки классов. Однако вам будет показан один трюк, позволяющий обой ти данное ограничение.
Создание проекта библиотеки классов
Для формирования нового проекта библиотеки в полной версии Visual Studio 2005 выберите тип проекта Class Library в диалоговом окне New Project. Затем пропустите следующий раздел главы и переходите к созданию классов, которые будут составлять библиотеку.
Если вы используете Visual С# Express, процесс создания нового проекта биб лиотеки будет немного более сложным. Несмотря на снижение функциональ ности, которому Microsoft подвергла Visual С# Express, если выполнить опи санные далее действия, все равно можно сформировать библиотеку классов.
1.При создании нового проекта создавайте Console Application (или Win dows Application).
Если вы не уверены в том, как это делается, вернитесь к главам 1, "Создание вашей первой Windows-программы на С#", и 2, "Создание консольного приложения на C#", Обычно библиотека классов формируется под видом консольного приложения.
2.В Solution Explorer удалите файл Program.cs, закройте и сохраните ре шение.
Поскольку библиотека классов не может содержать функцию Main ( ) , вы просто удаляете файл с ней.
3.Запустите Блокнот Windows или другой обычный текстовый редактор и от кройте в нем файл ProjectName.csproj из вновь созданного вами проекта.
430 |
Часть VII. Дополнительные главы |
Он выглядит страшновато, но это всего лишь масса информации о программе, за писанная с использованием языка XML.
4.Воспользуйтесь командой меню Edit"=>Find для того, чтобы найти строку:
<OutputType>Exe</OutputType>
Если вы создали проект приложения Windows, а не консольного приложения, найдите строку
<OutputType>WinExe</OutputТуре>
Это примерно восьмая строка в файле.
5.Замените в найденной строке Ехе (или WinExe) на Library:
<OutputType>Library</OutputType >
Вот и все!
6.Сохраните файл и заново откройте проект в Visual С# Express.
7.Добавляйте в проект новые классы и работайте. Только убедитесь, что вы не раз местили где-то в проекте функцию Main ().
Когда вы соберете новый проект, то получите . DLL-файл, а не . ЕХЕ-файл.
Создание классов для библиотеки
После того как вы сформировали проект библиотеки классов, вы создаете классы, составляющие эту библиотеку. Приведенный далее пример ClassLibrary демонстрирует простую библиотеку классов, которую вы сможете увидеть в действии (в примере показан как исходный текст библио теки, так и описываемого далее драйвера).
//ClassLibrary - простая библиотека классов и ее
//программа-драйвер
//Файл ClassLibrary.cs
using System;
namespace ClassLibrary
{
public class MyLibrary
{
public void LibraryFunctionl()
{
Console.WriteLine("Это LibraryFunctionl()");
}
public int LibraryFunction2(int input)
{
Console.Write("Это LibraryFunction2(), " + "возвращает { о } , input);
return input; // Возвращает аргумент
}
}
//Драйвер — в отдельном проекте
//Файл Program.cs
using System;
Глава 19. Работа с файлами и библиотеками |
431 |