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:

VS Simboli del compilatore

(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

inserisci la descrizione dell'immagine qui

Esempio di codice che salterà del codice:

public void Init()
{
    #if !IGNOREREFRESHDB
    // will skip code here
     db.Initialize();
    #endif
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow