C# Language
Direttive preprocessore
Ricerca…
Sintassi
- #define [symbol] // Definisce un simbolo del compilatore.
- #undef [symbol] // Undefines un simbolo del compilatore.
- #warning [messaggio di avviso] // Genera un avvertimento del compilatore. Utile con #if.
- #error [messaggio di errore] // Genera un errore del compilatore. Utile con #if.
- #line [numero linea] (nome file) // Sovrascrive il numero di riga del compilatore (e facoltativamente il nome del file sorgente). Utilizzato con modelli di testo T4 .
- #pragma warning [disable | restore] [warning numbers] // Disabilita / ripristina gli avvisi del compilatore.
- #pragma checksum " [nomefile] " " [guid] " " [checksum] " // Convalida il contenuto di un file sorgente.
- #region [nome regione] // Definisce una regione di codice comprimibile.
- #endregion // Termina un blocco dell'area del codice.
- #if [condizione] // Esegue il codice qui sotto se la condizione è vera.
- #else // Utilizzato dopo un #if.
- #elif [condizione] // Utilizzato dopo un #if.
- #endif // Termina un blocco condizionale avviato con #if.
Osservazioni
Le direttive del preprocessore sono generalmente utilizzate per rendere i programmi di origine facili da modificare e facili da compilare in diversi ambienti di esecuzione. Le direttive nel file sorgente indicano al preprocessore di eseguire azioni specifiche. Ad esempio, il preprocessore può sostituire i token nel testo, inserire il contenuto di altri file nel file sorgente o sopprimere la compilazione di parte del file rimuovendo sezioni di testo. Le linee del preprocessore vengono riconosciute e eseguite prima dell'espansione macro. Pertanto, se una macro si espande in qualcosa che assomiglia a un comando del preprocessore, tale comando non viene riconosciuto dal preprocessore.
Le istruzioni di preprocessore utilizzano lo stesso set di caratteri delle istruzioni del file di origine, con l'eccezione che le sequenze di escape non sono supportate. Il set di caratteri utilizzato nelle istruzioni del preprocessore è uguale al set di caratteri di esecuzione. Il preprocessore riconosce anche i valori dei caratteri negativi.
Espressioni condizionali
Le espressioni condizionali ( #if
, #elif
, ecc.) Supportano un sottoinsieme limitato di operatori booleani. Loro sono:
-
==
e!=
. Questi possono essere utilizzati solo per verificare se il simbolo è vero (definito) o falso (non definito) -
&&
,||
,!
-
()
Per esempio:
#if !DEBUG && (SOME_SYMBOL || SOME_OTHER_SYMBOL) && RELEASE == true
Console.WriteLine("OK!");
#endif
compilerebbe il codice che stampa "OK!" alla console se DEBUG
non è definito, sono definiti SOME_SYMBOL
o SOME_OTHER_SYMBOL
e RELEASE
è definito.
Nota: queste sostituzioni vengono eseguite in fase di compilazione e pertanto non sono disponibili per l'ispezione in fase di esecuzione. Il codice eliminato tramite l'uso di #if
non fa parte dell'output del compilatore.
Vedere anche: Direttive preprocessore C # a MSDN.
Espressioni condizionali
Quando viene compilato quanto segue, verrà restituito un valore diverso a seconda delle direttive definite.
// Compile with /d:A or /d:B to see the difference
string SomeFunction()
{
#if A
return "A";
#elif B
return "B";
#else
return "C";
#endif
}
Le espressioni condizionali vengono in genere utilizzate per registrare informazioni aggiuntive per le build di debug.
void SomeFunc()
{
try
{
SomeRiskyMethod();
}
catch (ArgumentException ex)
{
#if DEBUG
log.Error("SomeFunc", ex);
#endif
HandleException(ex);
}
}
Generazione di avvisi ed errori del compilatore
Gli avvertimenti del compilatore possono essere generati usando la direttiva #warning
e gli errori possono essere generati anche usando la direttiva #error
.
#if SOME_SYMBOL
#error This is a compiler Error.
#elif SOME_OTHER_SYMBOL
#warning This is a compiler Warning.
#endif
Definizione e annullamento della definizione dei simboli
Un simbolo del compilatore è una parola chiave definita in fase di compilazione che può essere controllata per eseguire in modo condizionato specifiche sezioni di codice.
Esistono tre modi per definire un simbolo del compilatore. Possono essere definiti tramite codice:
#define MYSYMBOL
Possono essere definiti in Visual Studio, in Proprietà progetto> Crea> Simboli di compilazione condizionale:
(Si noti che DEBUG
e TRACE
hanno le proprie caselle di controllo e non è necessario specificare esplicitamente.)
Oppure possono essere definiti in fase di compilazione usando l' csc.exe
/define:[name]
sul compilatore C #, csc.exe
.
Puoi anche simboli indefiniti usando la direttiva #undefine
.
L'esempio più diffuso di questo è il simbolo DEBUG
, che viene definito da Visual Studio quando un'applicazione viene compilata in modalità Debug (rispetto alla modalità di rilascio).
public void DoBusinessLogic()
{
try
{
AuthenticateUser();
LoadAccount();
ProcessAccount();
FinalizeTransaction();
}
catch (Exception ex)
{
#if DEBUG
System.Diagnostics.Trace.WriteLine("Unhandled exception!");
System.Diagnostics.Trace.WriteLine(ex);
throw;
#else
LoggingFramework.LogError(ex);
DisplayFriendlyErrorMessage();
#endif
}
}
Nell'esempio sopra, quando si verifica un errore nella business logic dell'applicazione, se l'applicazione è compilata in modalità Debug (e il simbolo DEBUG
è impostato), l'errore verrà scritto nel log di traccia e l'eccezione verrà reimpostata generato per il debug. Tuttavia, se l'applicazione è compilata in modalità Release (e non viene impostato alcun simbolo DEBUG
), viene utilizzato un framework di registrazione per registrare l'errore in modo silenzioso e viene visualizzato un messaggio di errore amichevole all'utente finale.
Blocchi Regionali
Utilizza #region
e #endregion
per definire una regione di codice comprimibile.
#region Event Handlers
public void Button_Click(object s, EventArgs e)
{
// ...
}
public void DropDown_SelectedIndexChanged(object s, EventArgs e)
{
// ...
}
#endregion
Queste direttive sono utili solo quando un IDE che supporta regioni comprimibili (come Visual Studio ) viene utilizzato per modificare il codice.
Altre istruzioni per il compilatore
Linea
#line
controlla il numero di riga e il nome del file riportati dal compilatore durante l'emissione di avvisi ed errori.
void Test()
{
#line 42 "Answer"
#line filename "SomeFile.cs"
int life; // compiler warning CS0168 in "SomeFile.cs" at Line 42
#line default
// compiler warnings reset to default
}
Checksum di Pragma
#pragma checksum
consente la specifica di un checksum specifico per un database di programma generato (PDB) per il debug.
#pragma checksum "MyCode.cs" "{00000000-0000-0000-0000-000000000000}" "{0123456789A}"
Utilizzando l'attributo condizionale
Aggiungere un attributo Conditional
dallo spazio dei nomi System.Diagnostics
a un metodo è un modo pulito per controllare quali metodi vengono chiamati nelle build e quali no.
#define EXAMPLE_A
using System.Diagnostics;
class Program
{
static void Main()
{
ExampleA(); // This method will be called
ExampleB(); // This method will not be called
}
[Conditional("EXAMPLE_A")]
static void ExampleA() {...}
[Conditional("EXAMPLE_B")]
static void ExampleB() {...}
}
Disattivazione e ripristino degli avvisi del compilatore
È possibile disabilitare gli avvisi del compilatore utilizzando l' #pragma warning disable
e ripristinarli utilizzando il #pragma warning restore
:
#pragma warning disable CS0168
// Will not generate the "unused variable" compiler warning since it was disabled
var x = 5;
#pragma warning restore CS0168
// Will generate a compiler warning since the warning was just restored
var y = 8;
Sono ammessi numeri di avviso separati da virgola:
#pragma warning disable CS0168, CS0219
Il prefisso CS
è facoltativo e può anche essere mescolato (anche se questa non è una best practice):
#pragma warning disable 0168, 0219, CS0414
Preprocessori personalizzati a livello di progetto
È utile impostare la pre-elaborazione condizionale personalizzata a livello di progetto quando alcune azioni devono essere saltate, diciamo per i test.
Vai a Solution Explorer
-> Fai clic con il pulsante destro del mouse sul progetto per cui vuoi impostare la variabile su -> Properties
-> Build
-> Nel campo di ricerca Generale Conditional compilation symbols
e inserisci qui la variabile condizionale
Esempio di codice che salterà del codice:
public void Init()
{
#if !IGNOREREFRESHDB
// will skip code here
db.Initialize();
#endif
}