Szukaj…


Składnia

  • #define [symbol] // Definiuje symbol kompilatora.
  • #undef [symbol] // Nie definiuje symbolu kompilatora.
  • #warning [komunikat ostrzegawczy] // Generuje ostrzeżenie kompilatora. Przydatne z #if.
  • #error [komunikat o błędzie] // Generuje błąd kompilatora. Przydatne z #if.
  • #line [numer linii] (nazwa pliku) // Przesłania numer linii kompilatora (i opcjonalnie nazwę pliku źródłowego). Używany z szablonami tekstowymi T4 .
  • #pragma ostrzeżenie [wyłącz | przywróć] [numery ostrzegawcze] // Wyłącza / przywraca ostrzeżenia kompilatora.
  • #pragma suma kontrolna „ [nazwa pliku] ” „ [guid] ” „ [suma kontrolna] ” // Sprawdza zawartość pliku źródłowego.
  • #region [nazwa regionu] // Definiuje składany region kodu.
  • #endregion // Kończy blok regionu kodu.
  • #if [warunek] // Wykonuje poniższy kod, jeśli warunek jest spełniony.
  • #else // Używane po #if.
  • #elif [warunek] // Używany po #if.
  • #endif // Kończy blok warunkowy rozpoczęty od #if.

Uwagi

Dyrektywy preprocesora są zwykle używane do ułatwienia zmiany programów źródłowych i kompilacji w różnych środowiskach wykonawczych. Dyrektywy w pliku źródłowym nakazują preprocesorowi wykonanie określonych działań. Na przykład preprocesor może zastępować tokeny w tekście, wstawiać zawartość innych plików do pliku źródłowego lub blokować kompilację części pliku, usuwając sekcje tekstu. Linie preprocesora są rozpoznawane i przeprowadzane przed rozszerzeniem makr. Dlatego jeśli makro rozwija się w coś, co wygląda jak polecenie preprocesora, polecenie to nie jest rozpoznawane przez preprocesor.

Instrukcje preprocesora używają tego samego zestawu znaków, co instrukcje pliku źródłowego, z tym wyjątkiem, że sekwencje specjalne nie są obsługiwane. Zestaw znaków używany w instrukcjach preprocesora jest taki sam jak zestaw znaków wykonania. Preprocesor rozpoznaje również ujemne wartości znaków.

Wyrażenia warunkowe

Wyrażenia warunkowe ( #if , #elif , etc) czy wspierają ograniczony podzbiór operatorów logicznych. Oni są:

  • == i != . Można ich używać tylko do testowania, czy symbol jest prawdziwy (zdefiniowany) lub fałszywy (nie zdefiniowany)
  • && , || , !
  • ()

Na przykład:

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

skompiluje kod, który wypisuje „OK!” do konsoli, jeśli DEBUG nie jest zdefiniowany, SOME_SYMBOL lub SOME_OTHER_SYMBOL jest zdefiniowany, a RELEASE jest zdefiniowane.

Uwaga: Podstawienia te są wykonywane w czasie kompilacji i dlatego nie są dostępne do kontroli w czasie wykonywania. Kod wyeliminowany przez użycie #if nie jest częścią danych wyjściowych kompilatora.

Zobacz także: C # Dyrektywy preprocesora w MSDN.

Wyrażenia warunkowe

Po skompilowaniu następujących elementów, zwróci inną wartość w zależności od zdefiniowanych dyrektyw.

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

Wyrażenia warunkowe są zwykle używane do rejestrowania dodatkowych informacji dotyczących kompilacji debugowania.

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

        HandleException(ex);
    }
}

Generowanie ostrzeżeń i błędów kompilatora

Ostrzeżenia kompilatora można generować za pomocą dyrektywy #warning , a błędy można również generować za pomocą dyrektywy #error .

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

Definiowanie i niezdefiniowanie symboli

Symbol kompilatora to słowo kluczowe zdefiniowane w czasie kompilacji, które można sprawdzić, aby warunkowo wykonać określone sekcje kodu.

Istnieją trzy sposoby zdefiniowania symbolu kompilatora. Można je zdefiniować za pomocą kodu:

#define MYSYMBOL

Można je zdefiniować w Visual Studio, w obszarze Właściwości projektu> Kompilacja> Symbole kompilacji warunkowej:

Symbole kompilatora VS

(Pamiętaj, że DEBUG i TRACE mają własne pola wyboru i nie trzeba ich wyraźnie określać).

Lub można je zdefiniować w czasie kompilacji za pomocą przełącznika /define:[name] na kompilatorze C #, csc.exe .

Można także niezdefiniować symbole za pomocą dyrektywy #undefine .

Najbardziej rozpowszechnionym tego przykładem jest symbol DEBUG , który jest definiowany przez Visual Studio, gdy aplikacja jest kompilowana w trybie debugowania (w porównaniu z trybem wydania).

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

W powyższym przykładzie, gdy wystąpi błąd w logice biznesowej aplikacji, jeśli aplikacja zostanie skompilowana w trybie debugowania (i ustawiony jest symbol DEBUG ), błąd zostanie zapisany w dzienniku śledzenia, a wyjątek zostanie ponownie -rzucony do debugowania. Jeśli jednak aplikacja zostanie skompilowana w trybie Release (i nie zostanie ustawiony żaden symbol DEBUG ), do rejestrowania błędu po cichu zostanie użyte środowisko rejestrowania, a użytkownik końcowy wyświetli przyjazny komunikat o błędzie.

Bloki regionalne

Użyj #region i #endregion aby zdefiniować składany region kodu.

#region Event Handlers

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

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

#endregion

Te dyrektywy są korzystne tylko wtedy, gdy IDE obsługujące zwijane regiony (takie jak Visual Studio ) jest używane do edycji kodu.

Inne instrukcje kompilatora

Linia

#line kontroluje numer linii i nazwę pliku zgłaszane przez kompilator podczas wysyłania ostrzeżeń i błędów.

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
}

Suma kontrolna Pragma

#pragma checksum umożliwia określenie określonej sumy kontrolnej dla wygenerowanej bazy danych programu (PDB) do debugowania.

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

Korzystanie z atrybutu warunkowego

Dodanie atrybutu Conditional z System.Diagnostics nazw System.Diagnostics do metody to czysty sposób kontrolowania, które metody są wywoływane w twoich kompilacjach, a które nie.

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

Wyłączanie i przywracanie ostrzeżeń kompilatora

Możesz wyłączyć ostrzeżenia kompilatora za pomocą #pragma warning disable i przywrócić je za pomocą #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;

Dozwolone są numery rozdzielone przecinkami:

#pragma warning disable CS0168, CS0219

Prefiks CS jest opcjonalny i można go nawet mieszać (choć nie jest to najlepsza praktyka):

#pragma warning disable 0168, 0219, CS0414

Niestandardowe preprocesory na poziomie projektu

Wygodnie jest ustawić niestandardowe warunkowe przetwarzanie wstępne na poziomie projektu, gdy niektóre działania muszą zostać pominięte, powiedzmy w testach.

Idź do Solution Explorer -> Kliknij prawym przyciskiem myszy na projekcie, dla którego chcesz ustawić zmienną -> Properties -> Build -> Ogólnie znajdź pole Conditional compilation symbols i wprowadź tutaj zmienną warunkową

wprowadź opis zdjęcia tutaj

Przykład kodu, który pominie jakiś kod:

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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow