Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Подсказка
Вы новичок в разработке программного обеспечения? Директивы препроцессора не потребуются сразу. Сначала сосредоточьтесь на руководствах по началу работы и вернитесь сюда, когда для проектов требуется условная компиляция или конфигурация сборки.
Есть опыт на другом языке? Если вы знакомы с #ifdef C/C++ или условной компиляцией на других языках, директивы препроцессора C# работают аналогично. Перейдите к нужному синтаксису.
Директивы препроцессора C# сообщают компилятору, какой код следует включать, исключать или обрабатывать по-разному при сборке приложения. Это руководство может изменить итоговую программу. Директивы препроцессора всегда начинаются с # и должны отображаться в собственной строке (игнорируя ведущие пробелы). После директивы можно добавить конечный комментарий. Хотя языковой справочник документирует все доступные директивы, три группы охватывают повседневное использование:
-
Приложения на основе файлов (
#:) — настройка файловых приложений. -
Условная компиляция (
#if/#elif/#else/#endif) — включение или исключение кода на основе конфигурации сборки или целевой платформы. -
Подавление предупреждений (
#pragma warning) — подавление или восстановление определенных предупреждений компилятора.
Директивы приложений, основанные на файлах
Начиная с C# 14 , приложения на основе файлов используют две дополнительные директивы:
-
#!— строка shebang , которая позволяет выполнять файл непосредственно в Unix (например,./Program.cs). Для этого требуется разрешение на выполнение для файла (chmod +x <file>). -
#:— директивы build-system, которые настраивают пакеты, параметры пакета SDK и другие параметры для однофайловых программ.
Используйте #:package для добавления пакета NuGet. Например, следующее приложение на основе файлов использует пакет Spectre.Console для отображения стилизованного вывода.
#!/usr/bin/env dotnet
#:package Spectre.Console@*
AnsiConsole.MarkupLine("[bold green]Hello[/] from a file-based app!");
Вы можете указать точную версию с помощью @, и использовать @* для извлечения последней версии. Добавьте несколько директив для включения дополнительных #:package пакетов:
#:package Serilog@3.1.1
Другие #: директивы позволяют ссылать на проекты, задавать свойства MSBuild или изменять пакет SDK:
#:project ../SharedLibrary/SharedLibrary.csproj
#:property PublishAot=false
#:sdk Microsoft.NET.Sdk.Web
Полный список директив см. в разделе "Приложения на основе файлов " и справочник по языку.
Условная компиляция
Используйте #if, #elif#elseи #endif для включения или исключения кода в зависимости от того, определен ли символ. Наиболее распространенными символами являются DEBUG (автоматически заданные для отладочных сборок) и целевые символы платформы, такие как NET10_0_OR_GREATER:
static void ConfigureLogging()
{
#if DEBUG
Console.WriteLine("Debug logging enabled — verbose output active.");
#else
Console.WriteLine("Release logging — errors only.");
#endif
}
Система сборки определяет DEBUG символ при сборке в конфигурации Debug. Вам не нужно определять его самостоятельно. Символы целевой платформы, такие как NET10_0_OR_GREATER и NET8_0_OR_GREATER позволяют писать код, который адаптируется к различным версиям .NET в проектах с несколькими целевыми объектами.
Символы можно объединить с логическими операторами: && (и) || (или) и ! (не):
static void ShowPlatformInfo()
{
#if NET10_0_OR_GREATER
Console.WriteLine("Running on .NET 10 or later.");
#elif NET8_0_OR_GREATER
Console.WriteLine("Running on .NET 8 or 9.");
#else
Console.WriteLine("Running on an older .NET version.");
#endif
}
Используйте #define в верхней части файла для определения собственных символов. Вы также можете определить символы для всего проекта с помощью DefineConstants свойства в файле проекта.
Подавление предупреждений
Используется #pragma warning disable для подавления определенных предупреждений компилятора и #pragma warning restore их повторного включения. Всегда определяйте подавление как можно более узко:
static void ProcessData()
{
try
{
// Some operation that might fail
var data = File.ReadAllText("config.json");
Console.WriteLine($"Config loaded: {data.Length} characters");
}
#pragma warning disable CS0168 // Variable is declared but never used
catch (FileNotFoundException ex)
#pragma warning restore CS0168
{
// Fall back to defaults — the exception details aren't needed here
Console.WriteLine("Config file not found, using defaults.");
}
}
Подсказка
Всегда указывайте номер предупреждения, например CS0168, вместо отключения всех предупреждений. Этот подход сохраняет целевое подавление и дает понять , почему предупреждение подавляется.