1629295407-c61bfe4caba98380ea3e7cdae6295416 (846200), страница 81
Текст из файла (страница 81)
Поэтому при использовании директивы #if символьное выражениеEXPERIMENTAL оценивается как истинное, и компилируется первая (из двух)WriteLine()-инструкция. Если удалить определение идентификатора experimental иперекомпилировать программу, первая WriteLine()-инструкция не скомпилируется,поскольку результат выполнения директивы #if будет оценен как ложный. ВтораяWriteLine()-инструкция скомпилируется обязательно, поскольку она не является частью#if-блока. Как упоминалось выше, в директиве #if можно использовать символьноевыражение.
Вот пример:// Использование символьного выражения.#define EXPERIMENTAL#define TRIALusing System;class Test {public static void Main() {#if EXPERIMENTALConsole.WriteLine("Компилируется для экспериментальной версии.");#endif#if EXPERIMENTAL && TRIALConsole.Error.WriteLine("Тестирование экспериментальной пробной версии.");#endifГлава 16. Пространства имен, препроцессор и компоновочные файлы443}}Console.WriteLine("Эта информация отображается во всех версиях.");Вот результаты выполнения этой программы:Компилируется для экспериментальной версии.Тестирование экспериментальной пробной версии.Эта информация отображается во всех версиях.В этом примере определяются два идентификатора, EXPERIMENTAL и TRIAL.Вторая WriteLine()-инструкция компилируется только в случае, если определены обаидентификатора.#else и #elifДиректива #else работает подобно else-инструкции в языке C#, т.е.
она предлагаетальтернативу на случай, если директива #if выявит ложный результат. Следующимипример представляет собой расширенный вариант предыдущего.// Демонстрация использования директивы #else.#define EXPERIMENTALusing System;class Test {public static void Main() {#if EXPERIMENTALConsole.WriteLine("Компилируется для экспериментальной версии.");#elseConsole.WriteLine("Компилируется для бета-версии.");#endif#if EXPERIMENTAL && TRIALConsole.Error.WriteLine("Тестирование экспериментальной пробной версии.");#elseConsole.Error.WriteLine("Это не экспериментальная пробная версия.");#endif}}Console.WriteLine("Эта информация отображается во всех версиях.");При выполнении этой программы получены такие результаты:Компилируется для экспериментальной версии.Это не экспериментальная пробная версия.Эта информация отображается во всех версиях.Поскольку идентификатор TRIAL не определен, компилируется #else-блок второйусловной последовательности инструкций.Обратите внимание на то, что директива #else отмечает одновременно как конец#if-блока, так и начало #else-блока, поскольку с любой директивой #if может бытьсвязана только одна директива #endif.444Часть I.
Язык C#Директива #elif означает “иначе если” и используется в if-else-if-цепочкахмноговариантной компиляции. С директивой #elif связано символьное выражение. Еслионо истинно, следующий за ним блок кода (последовательность_инструкций)компилируется, и другие #elif-выражения не проверяются, В противном случаетестируется следующий #elif-блок. Общая форма цепочки #elif-блоков имеетследующий вид:#if символьное_выражениепоследовательность_инструкций#elif символьное_выражениепоследовательность_инструкций#elif символьное_выражениепоследовательность_инструкций#elif символьное_выражениепоследовательность_инструкций#elif символьное_выражение...#endifРассмотрим пример:// Демонстрация использования директивы #elif.#define RELEASEusing System;class Test {public static void Main() {#if EXPERIMENTALConsole.WriteLine("Компилируется для экспериментальной версии.");#elif RELEASEConsole.WriteLine("Компилируется для бета-версии.");#elseConsole.WriteLine("Компилируется для внутреннего тестирования.");#endif#if TRIAL && !RELEASEConsole.WriteLine("Пробная версия.");#endifConsole.WriteLine("Эта информация отображается во всех версиях.");}}Результаты выполнения этой программы выглядят так:Компилируется для бета-версии.Эта информация отображается во всех версиях.#undefДиректива #undef аннулирует приведенное выше определение идентификатора,который указан после директивы.
Общая форма директивы #undef имеет следующий вид:#undef идентификаторГлава 16. Пространства имен, препроцессор и компоновочные файлы445Рассмотрим пример:#define SMALL#if SMALL// ...#undef SMALL// Здесь идентификатор SMALL уже не определен.После выполнения директивы #undef идентификатор SMALL больше не считаетсяопределенным.Директива #undef используется главным образом для того, чтобы разрешитьлокализацию идентификатора только в пределах нужных разделов кода.#errorДиректива #error вынуждает компилятор прекратить компиляцию. Онаиспользуется в целях отладки.Общая форма директивы #error имеет следующий вид:#error сообщение_об_ошибкеПри использовании директивы #error отображается заданное сообщение_об_ошибке.
Например, при обработке компилятором строки#error Это тестовая ошибка!процесс компиляции будет остановлен, а на экране появится сообщение “Это тестоваяошибка!”.#warningДиректива #warning подобна директиве #error, но она не извещает об ошибке, асодержит предупреждение. Процесс компиляции при этом не останавливается. Общаяформа директивы #warning имеет следующий вид:#warning предупреждающее_сообщение#lineДиректива #line устанавливает номер строки и имя файла, который содержитдирективу #line. Номер строки и имя файла используются во время компиляции привыводе сообщений об ошибках или предупреждений.
Общая форма записи директивы#line выглядит так:#line номер "имя_файла"Здесь элемент номер представляет собой любое положительное целое число, котороестанет новым номером строки, а необязательный элемент имя_файла - любой допустимыйидентификатор файла, который станет новым именем файла. Директива #line в основномиспользуется при отладке и в специальных приложениях.Чтобы вернуть нумерацию строк в исходное состояние, используйте ключевое словоdefault: #line default446Часть I. Язык C##region и #endregionДирективы #region и #endregion позволяют определить область, которуюможно будет разворачивать или сворачивать при использовании интегрированной средыразработки (IDE) Visual Studio. Вот общая форма использования этих директив:#region имя_области// последовательность_инструкций#endregionНетрудно догадаться, что элемент имя_области означает имя области.Компоновочные файлы и модификатор доступаinternalНеотъемлемой частью C#-программирования является компоновочный файл(assembly), который содержит информацию о развертывании программы и ее версии.Компоновочные файлы имеют важное значение для .NET-среды.
Согласно документацииMicrosoft, “компоновочные файлы являются строительными блоками среды .NETFramework.” Компоновочные файлы поддерживают механизм безопасного взаимодействиякомпонентов, межъязыковой работоспособности и управления версиями. Компоновочныйфайл также определяет область видимости.Компоновочный файл состоит из четырех разделов. Первый представляет собойдекларацию (manifest).
Декларация содержит информацию о компоновочном файле. Сюдаотносятся такие данные, как имя компоновочного файла, номер его версии, информация осоответствии типов и параметры “культурного уровня”. Второй раздел включаетметаданные, или информацию о типах данных, используемых в программе. В числе прочихдостоинств метаданных — обеспечение взаимодействия программ, написанных наразличных языках программирования. Третий раздел компоновочного файла содержитпрограммный код, который хранится в формате Microsoft Intermediate Language (MSIL).Наконец, четвертый раздел представляет собой ресурсы, используемые программой.К счастью, при использовании языка C# компоновочные файлы создаютсяавтоматически, без дополнительных (или с минимальными) усилий со стороныпрограммиста.
Дело в том, что выполняемый файл, создаваемый в результате компиляцииC#-программы, в действительности является компоновочным файлом, который содержитвыполняемый код программы и другую информацию. Следовательно, при компиляции C#программы автоматически создается компоновочный файл.Подробное рассмотрение компоновочных файлов выходит за рамки этой книги.(Компоновочные файлы — неотъемлемая часть .NET-разработки, а не средство языка C#.)Но одна часть языка C# напрямую связана с компоновочным файлом: модификатор доступаinternal. Вот о нем-то и пойдет речь в следующем разделе.Модификатор доступа internalПомимо модификаторов доступа public, private и protected, с которыми выуже встречались в этой книге, в C# также определен модификатор internal.
Егоназначение — заявить о том, что некоторый член известен во всех файлах, входящих всостав компоновочного, но неизвестен вне его. Проще говоря, член, отмеченныймодификатором internal, известен только программе, но не где-то еще. Модификатордоступа internal чрезвычайно полезен при создании программных компонентов.Глава 16. Пространства имен, препроцессор и компоновочные файлы447Модификатор internal можно применить к классам и членам классов, а также кструктурам и членам структур. Модификатор internal можно также применить кобъявлениям интерфейсов и перечислений.Совместно с модификатором internal можно использовать модификаторprotected.