Sök…


Syntax

  • #define [symbol] // Definierar en kompilatorsymbol.
  • #undef [symbol] // Definierar en kompilatorsymbol.
  • #varning [varningsmeddelande] // Genererar en kompilatorvarning. Användbart med #if.
  • #error [felmeddelande] // Genererar ett kompilatorfel. Användbart med #if.
  • # line [ radnummer ] (filnamn) // åsidosätter kompilatorradnumret (och eventuellt källfilens namn). Används med T4-textmallar .
  • #pragma varning [inaktivera | återställa] [varningsnummer] // Inaktiverar / återställer kompilatorvarningar.
  • #pragma checksum " [filnamn] " " [guid] " " [checksum] " // Validerar innehållet i en källfil.
  • #region [ regionnamn ] // Definierar en hopfällbar kodregion.
  • #endregion // Avslutar ett kodregionblock.
  • #if [villkor] // Utför koden nedan om villkoret är sant.
  • #else // Används efter en #if.
  • #elif [villkor] // Används efter en #if.
  • #endif // Avslutar ett villkorat block som startats med #if.

Anmärkningar

Förbehandlingsdirektiv används vanligtvis för att göra källprogrammen enkla att ändra och lätta att kompilera i olika exekveringsmiljöer. Direktiv i källfilen ber förförädlaren att utföra specifika åtgärder. Exempelvis kan förbehandlaren ersätta tokens i texten, infoga innehållet i andra filer i källfilen eller undertrycka kompilering av en del av filen genom att ta bort textavsnitt. Förprocessorlinjer erkänns och genomförs före makroutvidgning. Därför, om ett makro expanderar till något som ser ut som ett förbehandlarkommando, känns igen det kommandot inte av förbehandlaren.

Förprocessorns uttalanden använder samma teckenuppsättning som uttalanden om källfiler, med undantag för att escape-sekvenser inte stöds. Teckenuppsättningen som används i förberedande uttalanden är densamma som exekveringsteckenuppsättningen. Förbehandlaren känner också igen negativa teckenvärden.

Villkorliga uttryck

Villkorade uttryck ( #if , #elif , etc) stöder en begränsad delmängd av booleska operatörer. Dom är:

  • == och != . Dessa kan endast användas för att testa om symbolen är sann (definierad) eller falsk (inte definierad)
  • && , || , !
  • ()

Till exempel:

#if !DEBUG && (SOME_SYMBOL || SOME_OTHER_SYMBOL) && RELEASE == true
Console.WriteLine("OK!");
#endif

skulle sammanställa kod som skriver ut "OK!" till konsolen om DEBUG inte är definierat definieras antingen SOME_SYMBOL eller SOME_OTHER_SYMBOL och RELEASE definieras.

Obs: Dessa ersättningar görs vid sammanställningstid och är därför inte tillgängliga för inspektion vid körning. Kod som elimineras genom användning av #if är inte en del av kompilatorns utgång.

Se även: C # Preprocessor-direktiv på MSDN.

Villkorliga uttryck

När följande sammanställs returnerar det ett annat värde beroende på vilka direktiv som definieras.

// 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
}

Villkorliga uttryck används vanligtvis för att logga in ytterligare information för felsökning.

void SomeFunc()
{
    try
    {
        SomeRiskyMethod();
    }
    catch (ArgumentException ex)
    {
        #if DEBUG
        log.Error("SomeFunc", ex);
        #endif

        HandleException(ex);
    }
}

Generera kompilatorvarningar och fel

Kompilatorvarningar kan genereras med hjälp av #warning , och fel kan också genereras med #error direktivet.

#if SOME_SYMBOL
#error This is a compiler Error.
#elif SOME_OTHER_SYMBOL
#warning This is a compiler Warning.
#endif

Definiera och definiera symboler

En kompilatorsymbol är ett nyckelord som definieras vid kompileringstid som kan kontrolleras för att villkorligt utföra specifika kodavsnitt.

Det finns tre sätt att definiera en kompilatorsymbol. De kan definieras via kod:

#define MYSYMBOL

De kan definieras i Visual Studio, under Projektegenskaper> Bygg> Symboler för villkorlig sammanställning:

VS-kompilatorsymboler

(Observera att DEBUG och TRACE har sina egna kryssrutor och behöver inte anges uttryckligen.)

Eller de kan definieras vid kompileringstid med /define:[name] -omkopplaren på C # -kompilatorn, csc.exe .

Du kan också odefiniera symboler med #undefine direktivet.

Det vanligaste exemplet på detta är DEBUG symbolen, som definieras av Visual Studio när ett program kompileras i felsökningsläge (kontra frisläppsläge).

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
    }
}

I exemplet ovan, när ett fel inträffar i applikationens affärslogik, om applikationen är kompilerad i felsökningsläge (och DEBUG symbolen är inställd), kommer felet att skrivas till spårloggen, och undantaget kommer att -gjord för felsökning. Men om applikationen är kompilerad i släppläge (och ingen DEBUG symbol är inställd) används ett loggningsram för att tyst logga felet och ett vänligt felmeddelande visas för slutanvändaren.

Regionblock

Använd #region och #endregion att definiera en hopfällbar kodregion.

#region Event Handlers

public void Button_Click(object s, EventArgs e)
{
    // ...
}

public void DropDown_SelectedIndexChanged(object s, EventArgs e)
{
    // ...
}

#endregion

Dessa direktiv är endast fördelaktiga när en IDE som stöder hopfällbara regioner (som Visual Studio ) används för att redigera koden.

Andra kompilatorinstruktioner

Linje

#line styr linjenumret och filnamnet som rapporteras av kompilatorn när du anger varningar och fel.

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
}

Pragma Checksum

#pragma checksum tillåter specifikation av en specifik kontrollsumma för en genererad programdatabas (PDB) för felsökning.

#pragma checksum "MyCode.cs" "{00000000-0000-0000-0000-000000000000}" "{0123456789A}"

Använda villkoret attribut

Lägga till ett Conditional attribut från System.Diagnostics namnutrymme till en metod är ett rent sätt att kontrollera vilka metoder som kallas i dina builds och vilka inte.

#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() {...}
}

Inaktivera och återställa kompilatorvarningar

Du kan inaktivera kompilatorvarningar med hjälp av #pragma warning disable och återställa dem med #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;

Kommaseparerade varningsnummer är tillåtna:

#pragma warning disable CS0168, CS0219

CS prefixet är valfritt och kan till och med blandas (även om detta inte är en bästa praxis):

#pragma warning disable 0168, 0219, CS0414

Anpassade förprocessorer på projektnivå

Det är bekvämt att ställa in anpassad villkorad förbehandling på projektnivå när vissa åtgärder måste hoppas över, låt oss säga för tester.

Gå till Solution Explorer -> Klicka på höger mus på projektet du vill ställa in variabeln till -> Properties -> Build -> I allmänhet hitta fält Conditional compilation symbols och ange din villkorliga variabel här

ange bildbeskrivning här

Kodexempel som hoppar över någon kod:

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow