Директивы препроцессора в C#

В этом уроке мы узнаем о директивах препроцессора C#, а также о том, когда, почему и как они используются.

Как следует из названия, директивы препроцессора представляют собой блок операторов, который обрабатывается до начала компиляции.

Директивы препроцессора — это команды компилятора, которые влияют на процесс его работы.

Эти команды определяют, какие блоки кода нужно компилировать или как, например, обрабатывать определенные ошибки и предупреждения.

Директива препроцессора C# начинается с символарешетки # и не может занимать более одной строки. Директивы заканчиваются символом новой строкой, а не точкой с запятой ;.

Директива

Описание

Синтаксис

#if

Проверяет, является ли препроцессорное выражение истинным или нет.

#if препроцессорное-выражение
   код для компиляции
#endif

#elif

Используется вместе с #if для проверки нескольких препроцессорных выражений.

#if препроцессорное-выражение-1
   код для компиляции
#elif препроцессорное-выражение-2
   код для компиляции
#endif

#else

Используется вместе с #if для создания условных ветвлений.

#if препроцессорное-выражение
   код для компиляции
#elif
   код для компиляции
#endif

#endif

Используется вместе с #if для обозначения конца условной директивы.

#if препроцессорное-выражение
   код для компиляции
#endif

#define

Используется для определения идентификатора

#define ИДЕНТИФИКАТОР

#undef

Используется для отмены определения идентификатора.

#undef ИДЕНТИФИКАТОР

#warning

Позволяет генерировать предупреждение 1 уровня из кода.

#warning сообщение-предупреждения

#error

Позволяет генерировать ошибку из кода.

#error сообщение-ошибки

#line

Используется для задания номера строки и имени файла, сообщаемого макросами препроцессора.

#line номер-строки имя-файла

#region

Позволяет обозначить область, которую можно развернуть или свернуть при использовании редактора кода Visual Studio.

#region описание-области
  блок кода
#endregion

#endregion

Закрывает область, определенную директивой #region.

#region описание-области
 блок кода
#endregion

#pragma

Дает компилятору специальные инструкции для компиляции файла, в котором он работает.

#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#.

codechick

СodeСhick.io - простой и эффективный способ изучения программирования.

2024 ©