Директивы препроцессора в C#
В этом уроке мы узнаем о директивах препроцессора C#, а также о том, когда, почему и как они используются.
Как следует из названия, директивы препроцессора представляют собой блок операторов, который обрабатывается до начала компиляции.
Директивы препроцессора — это команды компилятора, которые влияют на процесс его работы.
Эти команды определяют, какие блоки кода нужно компилировать или как, например, обрабатывать определенные ошибки и предупреждения.
Директива препроцессора C# начинается с символарешетки #
и не может занимать более одной строки. Директивы заканчиваются символом новой строкой, а не точкой с запятой ;
.
Директива |
Описание |
Синтаксис |
|
Проверяет, является ли препроцессорное выражение истинным или нет. |
#if препроцессорное-выражение |
|
Используется вместе с |
#if препроцессорное-выражение-1 |
|
Используется вместе с |
#if препроцессорное-выражение |
|
Используется вместе с |
#if препроцессорное-выражение |
|
Используется для определения идентификатора |
#define ИДЕНТИФИКАТОР |
|
Используется для отмены определения идентификатора. |
#undef ИДЕНТИФИКАТОР |
|
Позволяет генерировать предупреждение 1 уровня из кода. |
#warning сообщение-предупреждения |
|
Позволяет генерировать ошибку из кода. |
#error сообщение-ошибки |
|
Используется для задания номера строки и имени файла, сообщаемого макросами препроцессора. |
#line номер-строки имя-файла |
|
Позволяет обозначить область, которую можно развернуть или свернуть при использовании редактора кода Visual Studio. |
#region описание-области |
|
Закрывает область, определенную директивой |
#region описание-области |
|
Дает компилятору специальные инструкции для компиляции файла, в котором он работает. |
#pragma название-инструкции аргументы-инструкции |
Директива #define
- Директива
#define
позволяет определять идентификатор. - Идентификаторы, которые были определены при использовании
#if
, будут иметь значениеtrue
. - Идентификаторы могут использоваться для указания условий компиляции.
Синтаксис
#define ИДЕНТИФИКАТОР
Пример использования
#define TESTING
Здесь TESTING
— это идентификатор.
Директива #if
- Директива
#if
используется для проверки препроцессорного выражения. - Препроцессорное выражение состоит из комбинации идентификаторов и таких операторов, как && (И), || (ИЛИ), ! (НЕ).
- За директивой
#if
следует директива#endif
. - Код внутри директивы
#if
компилируется только в том случае, если выражение, проверенное с помощью#if
истинно.
Синтаксис
#if препроцессорное-выражение
код для компиляции
#endif
Пример использования
#if TESTING
Console.WriteLine("Сейчас в TESTING");
#endif
Пример 1. Используем директиву #if
#define CSHARP
using System;
namespace Directive
{
class ConditionalDirective
{
public static void Main(string[] args)
{
#if (CSHARP)
Console.WriteLine("Идентификатор CSHARP определен.");
#endif
}
}
}
Вывод:
Идентификатор CSHARP определен.
В приведенной выше программе идентификатор CSHARP определяется с помощью директивы #define
в начале программы. Внутри метода Main()
директива #if
используется для проверки истинности CSHARP. Блок кода внутри директивы #if
компилируется, только если CSHARP определен.
Директива #elif
- Директива
#elif
используется вместе с директивой#if
, которая позволяет нам создавать составное условие. #elif
используется при тестировании нескольких препроцессорных выражений.- Код внутри директивы
#elif
компилируется только в том случае, если выражение, проверенное с помощью#elif
истинно.
Синтаксис
#if препроцессорное-выражение-1
код для компиляции
#elif препроцессорное-выражение-2
код для компиляции
#endif
Пример использования
#if TESTING
Console.WriteLine("Сейчас в TESTING");
#elif TRAINING
Console.WriteLine("Сейчас в TRAINING");
#endif
Директива #else
- Директива
#else
используется вместе с директивой#if
. - Если ни одно из выражений в предыдущих директивах
#if
и#elif
не является истинным, будет скомпилирован код внутри директивы#else
.
Синтаксис
#if препроцессорное-выражение-1
код для компиляции
#elif препроцессорное-выражение-2
код для компиляции
#else
код для компиляции
#endif
Пример использования
#if TESTING
Console.WriteLine("Сейчас в TESTING");
#elif TRAINING
Console.WriteLine("Сейчас в TRAINING");
#else
Console.WriteLine("Не TESTING и не TRAINING");
#endif
Директива #endif
- Директива
#endif
используется для обозначения конца директивы#if
.
Синтаксис
#if препроцессорное-выражение-1
код для компиляции
#endif
Пример использования
#if TESTING
Console.WriteLine("Сейчас в TESTING");
#endif
Пример 2. Используем условные директивы (#if, #elif, #else, #endif)
#define CSHARP
#undef PYTHON
using System;
namespace Directive
{
class ConditionalDirective
{
static void Main(string[] args)
{
#if (CSHARP && PYTHON)
Console.WriteLine("CSHARP и PYTHON определены");
#elif (CSHARP && !PYTHON)
Console.WriteLine("Идентификатор CSHARP определен, PYTHON не определен");
#elif (!CSHARP && PYTHON)
Console.WriteLine("Идентификатор PYTHON определен, CSHARP не определен");
#else
Console.WriteLine("CSHARP и PYTHON не определены");
#endif
}
}
}
Вывод:
Идентификатор CSHARP определен, PYTHON не определен
В этом примере мы использовали директивы #elif
и #else
. Эти директивы используются, когда необходимо протестировать несколько условий. Кроме того, чтобы сформировать препроцессорное выражение, идентификаторы можно комбинировать с помощью логических операторов.
Директива #warning
- Директива
#warning
позволяет генерировать предупреждение 1 уровня.
Синтаксис
#warning сообщение-предупреждения
Пример 3. Используем директиву #warning
using System;
namespace Directives
{
class WarningDirective
{
public static void Main(string[] args)
{
#if (!CSHARP)
#warning CSHARP не определен
#endif
Console.WriteLine("пример директивы #warning");
}
}
}
Вывод:
Program.cs(10,26): warning CS1030: #warning: 'CSHARP не определен' [/home/myuser/csharp/directives-project/directives-project.csproj]
пример директивы #warning
После запуска программы мы увидим результат, указанный выше. Текст представляет собой предупреждающее сообщение. Здесь мы определяем и генерируем предупреждение с помощью директивы #warning
.
Обратите внимание, что операторы после директивы #warning
также выполняются. Это означает, что директива #warning
не завершает программу, а просто выдает предупреждение.
Директива #error
- Директива
#error
позволяет генерировать ошибку.
Синтаксис
#error сообщение-ошибки
Пример 4. Используем директиву #error
using System;
namespace Directive
{
class Error
{
public static void Main(string[] args)
{
#if (!CSHARP)
#error CSHARP не определен
#endif
Console.WriteLine("пример директивы #error");
}
}
}
Вывод:
Program.cs(10,24): error CS1029: #error: 'CSHARP не определен' [/home/myuser/csharp/directives-project/directives-project.csproj]
The build failed. Please fix the build errors and run again.
Программа завершится, и C# не напечатает строку "пример директивы #error"
не будет напечатана, как это было в директиве #warning
.
Директива #line
- Директива #line используется для задания номера строки и имени файла, сообщаемого макросами препроцессора.
Синтаксис
#line номер-строки имя-файла
Пример использования
#line 50 "fakeprogram.cs"
Пример 5. Используем директиву #line
using System;
namespace Directive
{
class Error
{
public static void Main(string[] args)
{
#line 200 "AnotherProgram.cs"
#warning Фактическое предупреждение, созданное Program.cs в строке 10
}
}
}
Вывод:
AnotherProgram.cs(200,22): warning CS1030: #warning: 'Фактическое предупреждение, созданное Program.cs в строке 10' [/home/myuser/csh arp/directive-project/directive-project.csproj]
Мы сохранили приведенный выше пример как Program.cs
. Предупреждение было фактически сгенерировано программой Program.cs
в строке 10. Используя директиву #line
, мы изменили номер строки на 200, а имя файла — на AnotherProgram.cs
.
Директива #region и #endregion
- Директива #region позволяет нам определять блок кода, который можно будет сворачивать и разворачивать при использовании редактора кода Visual Studio.
- Эта директива используется для структурирования кода.
- Блок #region не может пересекаться с блоком #if. Однако блок #region можно вложить в блок #if, а блок #if — в блок #region.
- Директива #endregion должна указываться в конце блока #region.
Синтаксис
#region описание-области
блок кода
#endregion
Пример 6. Используем директиву #region
using System;
namespace Directive
{
class Region
{
public static void Main(string[] args)
{
#region Hello
Console.WriteLine("Привет");
Console.WriteLine("Привет");
Console.WriteLine("Привет");
Console.WriteLine("Привет");
Console.WriteLine("Привет");
#endregion
}
}
}
Вывод:
Привет
Привет
Привет
Привет
Привет
Директива #pragma
- Директива #pragma используется, чтобы дать компилятору некоторые специальные инструкции при компиляции файла, в котором он работает.
- Инструкция может включать или отключать некоторые предупреждения.
- C# поддерживает две инструкции
#pragma
:#pragma warning
: используется для включения или отключения предупреждений.- #
pragma checksum
: генерирует контрольные суммы для исходных файлов, которые будут использоваться при отладке.
Синтаксис
#pragma название-прагмы аргументы-прагмы
Пример использования
#pragma warning disable
Пример 7. Используем директиву #pragma
using System;
namespace Directive
{
class Error
{
public static void Main(string[] args)
{
#pragma warning disable
#warning Это предупреждение-1
#pragma warning restore
#warning Это предупреждение-2
}
}
}
Вывод:
Program.cs(12,22): warning CS1030: #warning: 'Это предупреждение-2' [/home/myuser/csharp/directive-project/directive-project.csproj]
Мы видим, что на экране отображается только второе предупреждение.
Так происходит, потому что мы изначально отключили все предупреждения перед первым предупреждением и восстановили их только перед вторым. По этой причине первое предупреждение было скрыто.
Мы также можем отключить конкретное предупреждение вместо всех предупреждений.
Чтобы узнать больше о #pragma
, почитайте статью о #pragma в официальном справочнике по C#.