Г. Шилдт - Полный справочник по C# (1160789), страница 82
Текст из файла (страница 82)
ВтораяWriteLine () -инструкция скомпилируется обязательно, поскольку она не являетсячастью # if-блока. Как упоминалось выше, в директиве # i f можно использовать символьное выражение. Вот пример:// Использование символьного выражения.#define EXPERIMENTAL#define TRIALusing System;class Test {public static void Main() {#if EXPERIMENTALConsole.WriteLine("Компилируется для экспериментальной версии.");#endif#if EXPERIMENTAL && TRIALConsole.Error.WriteLine("Тестирование экспериментальной пробной версии.");#endifГлава 16. Пространства имен, препроцессор и компоновочные файлы443Console.WriteLine("Эта информация отображается во всех версиях.")(Вот результаты выполнения этой программы:Компилируется для экспериментальной версии.Тестирование экспериментальной пробной версии.Эта информация отображается во всех версиях.В этом примере определяются два идентификатора, EXPERIMENTAL и TRIAL.
Вторая WriteLine () -инструкция компилируется только в случае, если определены обаидентификатора.#else и #elifДиректива # e l s e работает подобно else-инструкции в языке С#, т.е. она предлагает альтернативу на случай, если директива # i f выявит ложный результат. Следующий пример представляет собой расширенный вариант предьщущего.// Демонстрация использования директивы #else.#define EXPERIMENTALusing System;class Test {public static void Main() {#if EXPERIMENTALConsole.WriteLine("Компилируется для экспериментальной версии.");#elseConsole.WriteLine("Компилируется для бета-версии.");#endif#if EXPERIMENTAL && TRIALConsole.Error.WriteLine("Тестирование экспериментальной пробной версии.");#elseConsole.Error.WriteLine("Это не экспериментальная пробная версия.");#endifConsole.WriteLine("Эта информация отображается во всех версиях.");(При выполнении этой программы получены такие результаты:Компилируется для экспериментальной версии.Это не экспериментальная пробная версия.Эта информация отображается во всех версиях.Поскольку идентификатор TRIAL не определен, компилируется #е1эе-блок второйусловной последовательности инструкций.Обратите внимание на то, что директива # e l s e отмечает одновременно как конец#if-блока, так и начало telse-блока, поскольку с любой директивой #if может бытьсвязана только одна директива #endif.444Часть I.
Язык С#Директива # e l i f означает "иначе если" и используется в i f - e l s e- i f -цепочках многовариантной компиляции. С директивой # e l i f связано символьное выражение. Если оноистинно, следующий за ним блок кода (последовательность_инструкций) компилируется, и другие #elif-выражения не проверяются. В противном случае тестируется следующий telif-блок. Общая форма цепочки #el i f -блоков имеет следующий вид:#if символьное_выражениепоследовательность_инструкций# e l i f символьное_выражениепо следовательность_инструкций# e l i f символьно1е_выражениепоследовательность_инструкций# e l i f символьное_выражениепоследовательность_инструкций# e l i f символьное_выражение#endifРассмотрим пример:// Демонстрация использования директивы #elif.#define RELEASEusing Systemsclass 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Директива # e r r o r вынуждает компилятор прекратить компиляцию. Она используется в целях отладки.Общая форма директивы t e r r o r имеет следующий вид:terror сообщение__об_ошибкеПри использовании директивы t e r r o r отображается заданное сообщение_об_ошибке.
Например, при обработке компилятором строкиI t e r r o r Это тестовая ошибка!процесс компиляции будет остановлен, а на экране появится сообщение "Это тестовая ошибка!".#warningДиректива twarning подобна директиве t e r r o r , но она не извещает об ошибке, асодержит предупреждение. Процесс компиляции при этом не останавливается. Общаяформа директивы twarning имеет следующий вид:twarning предупреждающее_сообщение#lineДиректива t l i n e устанавливает номер строки и имя файла, который содержит директиву t l i n e . Номер строки и имя файла используются во время компиляции привыводе сообщений об ошибках или предупреждений. Общая форма записи директивыt l i n e выглядит так:t l i n e номер "имя_файла"Здесь элемент номер представляет собой любое положительное целое число, которое станет новым номером строки, а необязательный элемент имя___файла — любойдопустимый идентификатор файла, который станет новым именем файла.
Директиваt l i n e в основном используется при отладке и в специальных приложениях.Чтобы вернуть нумерацию строк в исходное состояние, используйте ключевое слово d e f a u l t :| t l i n e default446Часть I. Язык С## region и # end regionДирективы #region и #endregion позволяют определить область, которую можнобудет разворачивать или сворачивать при использовании интегрированной среды разработки (IDE) Visual Studio.
Вот общая форма использования этих директив:#region имя_области// последовательность_инструкций#endregionНетрудно догадаться, что элемент имя__области означает имя области.Компоновочные файлы и модификатор доступаinternalНеотъемлемой частью С#-программирования является компоновочный файл(assembly), который содержит информацию о развертывании программы и ее версии.Компоновочные файлы имеют важное значение для .NET-среды. Согласно документации Microsoft, "компоновочные файлы являются строительными блоками среды.NET Framework." Компоновочные файлы поддерживают механизм безопасного взаимодействия компонентов, межъязыковой работоспособности и управления версиями.Компоновочный файл также определяет область видимости.Компоновочный файл состоит из четырех разделов. Первый представляет собойдекларацию (manifest).
Декларация содержит информацию о компоновочном файле.Сюда относятся такие данные, как имя компоновочного файла, номер его версии,информация о соответствии типов и параметры "культурного уровня". Второй разделвключает метаданные, или информацию о типах данных, используемых в программе.В числе прочих достоинств метаданных — обеспечение взаимодействия программ, написанных на различных языках программирования. Третий раздел компоновочногофайла содержит программный код, который хранится в формате Microsoft IntermediateLanguage (MSIL).
Наконец, четвертый раздел представляет собой ресурсы, используемые программой.К счастью, при использовании языка С# компоновочные файлы создаются автоматически, без дополнительных (или с минимальными) усилий со стороны программиста. Дело в том, что выполняемый файл, создаваемый в результате компиляции С#программы, в действительности является компоновочным файлом, который содержитвыполняемый код программы и другую информацию. Следовательно, при компиляции Сопрограммы автоматически создается компоновочный файл.Подробное рассмотрение компоновочных файлов выходит за рамки этой книги.(Компоновочные файлы — неотъемлемая часть .NET-разработки, а не средство языкаС#.) Но одна часть языка С# напрямую связана с компоновочным файлом: модификатор доступа i n t e r n a l . Вот о нем-то и пойдет речь в следующем разделе.Модификатор доступа i n t e r n a lПомимо модификаторов доступа p u b l i c , p r i v a t e и p r o t e c t e d , с которыми выуже встречались в этой книге, в С# также определен модификатор i n t e r n a l .
Его назначение — заявить о том, что некоторый член известен во всех файлах, входящих всостав компоновочного, но неизвестен вне его. Проще говоря, член, отмеченный модификатором i n t e r n a l , известен только программе, но не где-то еще. Модификатордоступа i n t e r n a l чрезвычайно полезен при создании программных компонентов.Глава 16. Пространства имен, препроцессор и компоновочные файлы447Модификатор i n t e r n a l можно применить к классам и членам классов, а также кструктурам и членам структур. Модификатор i n t e r n a l можно также применить кобъявлениям интерфейсов и перечислений.Совместно с модификатором i n t e r n a l можно использовать модификаторp r o t e c t e d .
В результате будет установлен уровень доступа p r o t e c t e d i n t e r n a l , который можно применять только к членам класса. К члену, объявленному с использованием пары модификаторов p r o t e c t e d i n t e r n a l , можно получить доступ внутриего компоновочного файла. Он также доступен для производных типов.Рассмотрим пример использования модификатора доступа i n t e r n a l .// Использование модификатора доступа internal.using System;class InternalTest {internal int x;class InternalDemo {public static void Main() {InternalTest ob = new InternalTest();ob.x = 10; // Доступ возможен: х —в том же файле.Console.WriteLine("Значение ob.x: " + ob.x);Внутри класса I n t e r n a l T e s t поле х объявлено с использованием модификаторадоступа i n t e r n a l .
Это означает, что оно доступно в программе, как показано в кодекласса InternalDemo, но недоступно вне ее.448Часть I. Язык С#Полныйсправочник поДинамическая идентификациятипов, отражение иатрибутыЗта глава посвящена трем взаимосвязанным мощным средствам С#: динамической идентификации типов, отражению и атрибутам. Динамическая идентификация типов — это механизм, который позволяет распознать тип данных во время выполнения программы.