Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Suggerimento
Novità dello sviluppo di software? Non sono necessarie direttive del preprocessore immediatamente. Concentrarsi prima sui tutorial Get started e tornare qui quando i progetti richiedono la compilazione condizionale o la configurazione di build.
Esperienza in un'altra lingua? Se si ha familiarità con #ifdef in C/C++ o nella compilazione condizionale in altri linguaggi, le direttive del preprocessore C# funzionano in modo analogo. Passare alla sintassi necessaria.
Le direttive del preprocessore C# indicano al compilatore quale codice includere, escludere o trattare in modo diverso quando compila l'app. Queste indicazioni possono modificare il programma risultante. Le direttive del preprocessore iniziano sempre con # e devono essere visualizzate nella propria riga (ignorando gli spazi vuoti iniziali). È possibile aggiungere un commento finale dopo la direttiva . Mentre il linguaggio di riferimento documenta tutte le direttive disponibili, tre gruppi riguardano l'uso quotidiano:
-
App basate su file (
#:): configurare le app basate su file. -
Compilazione condizionale (
#if/#elif/#else/#endif): includere o escludere il codice in base alla configurazione di compilazione o al framework di destinazione. -
Eliminazione degli avvisi (
#pragma warning): eliminare o ripristinare avvisi specifici del compilatore.
Direttive applicazione basate su file
A partire da C# 14, le app basate su file usano due direttive aggiuntive:
-
#!— la riga shebang che consente di eseguire il file direttamente in Unix (ad esempio,./Program.cs). Questa operazione richiede l'autorizzazione di esecuzione da impostare nel file (chmod +x <file>). -
#:— direttive del sistema di compilazione che configurano pacchetti, impostazioni SDK e altre opzioni per programmi a file singolo.
Usare #:package per aggiungere un pacchetto NuGet. Ad esempio, la seguente app basata su file utilizza il pacchetto Spectre.Console per effettuare il rendering dell'output con stile.
#!/usr/bin/env dotnet
#:package Spectre.Console@*
AnsiConsole.MarkupLine("[bold green]Hello[/] from a file-based app!");
È possibile specificare una versione esatta con @o usare @* per eseguire il pull della versione più recente. Aggiungere direttive #:package multiple per includere altri pacchetti:
#:package Serilog@3.1.1
Altre #: direttive consentono di fare riferimento a progetti, impostare le proprietà di MSBuild o modificare l'SDK:
#:project ../SharedLibrary/SharedLibrary.csproj
#:property PublishAot=false
#:sdk Microsoft.NET.Sdk.Web
Per l'elenco completo delle direttive, vedere App basate su file e informazioni di riferimento sul linguaggio.
Compilazione condizionale
Usare #if, #elif#else, e #endif per includere o escludere il codice in base alla definizione di un simbolo. I simboli più comuni sono DEBUG (impostati automaticamente per le compilazioni di debug) e i simboli del framework di destinazione, ad esempio 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
}
Il sistema di compilazione definisce il DEBUG simbolo quando si compila nella configurazione di debug. Non è necessario definirlo manualmente. I simboli del framework di destinazione, ad NET10_0_OR_GREATER esempio e NET8_0_OR_GREATER consentono di scrivere codice che si adatta a diverse versioni di .NET nei progetti con più destinazioni.
È possibile combinare i simboli con operatori logici: && (e), || (o) e ! (non):
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
}
Usare #define nella parte superiore di un file per definire i propri simboli. È anche possibile definire simboli per l'intero progetto usando la DefineConstants proprietà nel file di progetto.
Eliminazione degli avvisi
Usare #pragma warning disable per eliminare avvisi specifici del compilatore e #pragma warning restore riabilitarli. Definire sempre l'ambito dell'eliminazione nel modo più stretto possibile:
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.");
}
}
Suggerimento
Specificare sempre il numero di avviso, ad esempio CS0168, anziché disabilitare tutti gli avvisi. Questo approccio mantiene l'eliminazione mirata e rende chiaro il motivo per cui viene eliminato un avviso.