Direktiv för förprocessorer

Tips/Råd

Är du nybörjare på att utveckla programvara? Du behöver inte förprocessordirektiv direkt. Fokusera på Komma igång-självstudierna först och återkom hit när dina projekt kräver villkorlig kompilering eller byggkonfiguration.

Har du erfarenhet av ett annat språk? Om du är bekant med #ifdef C/C++ eller villkorlig kompilering på andra språk fungerar C#-förprocessordirektiv på liknande sätt. Skumma igenom till den syntax du behöver.

C#-förprocessordirektiv talar om för kompilatorn vilken kod som ska inkluderas, exkluderas eller behandlas på ett annat sätt när appen skapas. Den här vägledningen kan ändra det resulterande programmet. Förprocessordirektiv börjar alltid med # och måste visas på sin egen rad (ignorera inledande blanksteg). Du kan lägga till en avslutande kommentar efter direktivet. Språkreferensen dokumenterar alla tillgängliga direktiv, men tre grupper omfattar daglig användning:

  • Filbaserade appar (#:) – konfigurera filbaserade appar.
  • Villkorsstyrd kompilering (#if / #elif / #else / #endif) – inkludera eller exkludera kod baserat på byggkonfiguration eller målramverk.
  • Varningsundertryckning (#pragma warning) – ignorera eller återställa specifika kompilatorvarningar.

Filbaserade appdirektiv

Från och med C# 14 använder filbaserade appar ytterligare två direktiv:

  • #! — den shebang-rad som gör det möjligt att köra filen direkt på Unix (till exempel ./Program.cs). Detta kräver att körningsbehörigheten anges för filen (chmod +x <file>).
  • #: — build-system-direktiv som konfigurerar paket, SDK-inställningar och andra alternativ för enfilsprogram.

Använd #:package för att lägga till ett NuGet-paket. Följande filbaserade app använder Spectre.Console till exempel paketet för att återge formaterade utdata:

#!/usr/bin/env dotnet
#:package Spectre.Console@*

AnsiConsole.MarkupLine("[bold green]Hello[/] from a file-based app!");

Du kan ange en exakt version med @eller använda @* för att hämta den senaste versionen. Lägg till flera #:package direktiv för att inkludera fler paket:

#:package Serilog@3.1.1

Med andra #: direktiv kan du referera till projekt, ange MSBuild-egenskaper eller ändra SDK:t:

#:project ../SharedLibrary/SharedLibrary.csproj
#:property PublishAot=false
#:sdk Microsoft.NET.Sdk.Web

En fullständig lista över direktiv finns i Filbaserade appar och språkreferensen.

Villkorsstyrd kompilering

Använd #if, #elif, #elseoch #endif för att inkludera eller exkludera kod baserat på om en symbol har definierats. De vanligaste symbolerna är DEBUG (anges automatiskt för felsökningsversioner) och målramverkssymboler som 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
}

Byggsystemet definierar symbolen DEBUG när du skapar felsökningskonfigurationen. Du behöver inte definiera det själv. Målramverkssymboler som NET10_0_OR_GREATER och NET8_0_OR_GREATER låter dig skriva kod som anpassar sig till olika .NET-versioner i projekt med flera mål.

Du kan kombinera symboler med logiska operatorer: && (och), || (eller) och ! (inte):

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
}

Använd #define längst upp i en fil för att definiera dina egna symboler. Du kan också definiera symboler för hela projektet med hjälp DefineConstants av egenskapen i projektfilen.

Varningsundertryckning

Använd #pragma warning disable för att förhindra specifika kompilatorvarningar och #pragma warning restore för att återaktivera dem. Begränsa alltid undertryckningen så snävt som möjligt:

    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.");
        }
    }

Tips/Råd

Ange alltid varningsnumret, till exempel CS0168, i stället för att inaktivera alla varningar. Den här metoden håller undertryckningen riktad och gör det tydligt varför en varning undertrycks.