C# Language
Präprozessor-Anweisungen
Suche…
Syntax
- #define [Symbol] // Definiert ein Compiler-Symbol.
- #undef [Symbol] // Definiert ein Compilersymbol.
- #warning [ warn message] // Erzeugt eine Compiler-Warnung. Nützlich mit #if.
- #error [Fehlermeldung] // Erzeugt einen Compiler-Fehler. Nützlich mit #if.
- #line [Zeilennummer] (Dateiname) // Überschreibt die Compiler-Zeilennummer (und optional den Namen der Quelldatei). Wird mit T4-Textvorlagen verwendet .
- #pragma warning [disable | restore] [Warnungsnummern] // Deaktiviert / stellt Compiler-Warnungen wieder her.
- #pragma Checksumme " [Dateiname] " " [Guid] " " [Prüfsumme] " // Überprüft den Inhalt einer Quelldatei.
- #region [ Regionsname ] // Definiert einen reduzierbaren Codebereich.
- #endregion // Beendet einen Codebereichsblock.
- #if [Bedingung] // Führt den folgenden Code aus, wenn die Bedingung erfüllt ist.
- #else // Wird nach einem #if verwendet.
- #elif [Bedingung] // Wird nach einem #if verwendet.
- #endif // Beendet einen Bedingungsblock, der mit #if begonnen wurde.
Bemerkungen
Präprozessoranweisungen werden normalerweise verwendet, um Quellprogramme leicht zu ändern und in verschiedenen Ausführungsumgebungen leicht zu kompilieren. Direktiven in der Quelldatei weisen den Präprozessor an, bestimmte Aktionen auszuführen. Der Präprozessor kann beispielsweise Tokens im Text ersetzen, den Inhalt anderer Dateien in die Quelldatei einfügen oder die Kompilierung eines Teils der Datei unterdrücken, indem Textabschnitte entfernt werden. Präprozessorzeilen werden vor der Makroerweiterung erkannt und ausgeführt. Wenn also ein Makro in etwas erweitert wird, das wie ein Präprozessorbefehl aussieht, wird dieser Befehl vom Präprozessor nicht erkannt.
Präprozessoranweisungen verwenden denselben Zeichensatz wie Anweisungen für Quelldateien, mit der Ausnahme, dass Escape-Sequenzen nicht unterstützt werden. Der in Präprozessoranweisungen verwendete Zeichensatz ist derselbe wie der Ausführungszeichensatz. Der Präprozessor erkennt auch negative Zeichenwerte.
Bedingte Ausdrücke
Bedingte Ausdrücke ( #if
, #elif
usw.) unterstützen eine begrenzte Teilmenge von Booleschen Operatoren. Sie sind:
-
==
und!=
. Diese können nur zum Testen verwendet werden, ob das Symbol wahr (definiert) oder falsch (nicht definiert) ist. -
&&
,||
!
-
()
Zum Beispiel:
#if !DEBUG && (SOME_SYMBOL || SOME_OTHER_SYMBOL) && RELEASE == true
Console.WriteLine("OK!");
#endif
würde einen Code kompilieren, der "OK!" Wenn DEBUG
nicht definiert ist, wird entweder SOME_SYMBOL
oder SOME_OTHER_SYMBOL
definiert und RELEASE
definiert.
Anmerkung: Diese Ersetzungen werden zur Kompilierzeit ausgeführt und stehen daher zur Laufzeit nicht zur Überprüfung zur Verfügung. Code, der durch Verwendung von #if
ist nicht Teil der Compiler-Ausgabe.
Siehe auch: C # -Prozessoranweisungen bei MSDN.
Bedingte Ausdrücke
Wenn das Folgende kompiliert wird, wird ein anderer Wert zurückgegeben, abhängig davon, welche Direktiven definiert sind.
// 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
}
Bedingte Ausdrücke werden normalerweise zum Protokollieren zusätzlicher Informationen für Debugbuilds verwendet.
void SomeFunc()
{
try
{
SomeRiskyMethod();
}
catch (ArgumentException ex)
{
#if DEBUG
log.Error("SomeFunc", ex);
#endif
HandleException(ex);
}
}
Generieren von Compiler-Warnungen und -Fehlern
Compiler-Warnungen können mit der Direktive #warning
generiert werden. Fehler können ebenfalls mit der Direktive #error
generiert werden.
#if SOME_SYMBOL
#error This is a compiler Error.
#elif SOME_OTHER_SYMBOL
#warning This is a compiler Warning.
#endif
Definieren und Definieren von Symbolen
Ein Compilersymbol ist ein Schlüsselwort, das zur Kompilierzeit definiert wird und auf das überprüft werden kann, um bestimmte Codeabschnitte bedingt auszuführen.
Es gibt drei Möglichkeiten, ein Compiler-Symbol zu definieren. Sie können über Code definiert werden:
#define MYSYMBOL
Sie können in Visual Studio unter Projekteigenschaften> Erstellen> Bedingte Kompilierungssymbole definiert werden:
(Beachten Sie, dass DEBUG
und TRACE
eigene Kontrollkästchen haben und nicht explizit angegeben werden müssen.)
Oder sie können zur Kompilierzeit mit dem Schalter /define:[name]
des C # -Compilers csc.exe
.
Sie können auch undefinierte Symbole mit der Direktive #undefine
.
Das häufigste Beispiel hierfür ist das DEBUG
Symbol, das von Visual Studio definiert wird, wenn eine Anwendung im Debug-Modus (Versionsmodus) kompiliert wird.
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
}
}
Wenn im obigen Beispiel ein Fehler in der Geschäftslogik der Anwendung auftritt und die Anwendung im Debug-Modus kompiliert wird (und das DEBUG
Symbol gesetzt ist), wird der Fehler in das Ablaufverfolgungsprotokoll geschrieben und die Ausnahme wird erneut angezeigt -würfen zum Debuggen. Wenn die Anwendung jedoch im Freigabemodus kompiliert wird (und kein DEBUG
Symbol festgelegt ist), wird ein Protokollierungsframework verwendet, um den Fehler unauffällig zu protokollieren, und dem Endbenutzer wird eine benutzerfreundliche Fehlermeldung angezeigt.
Regionsblöcke
Verwenden Sie #region
und #endregion
, um einen #region
#endregion
zu definieren.
#region Event Handlers
public void Button_Click(object s, EventArgs e)
{
// ...
}
public void DropDown_SelectedIndexChanged(object s, EventArgs e)
{
// ...
}
#endregion
Diese Anweisungen sind nur dann von Nutzen, wenn zum Bearbeiten des Codes eine IDE verwendet wird, die reduzierbare Bereiche unterstützt (z. B. Visual Studio ).
Andere Compiler-Anweisungen
Linie
#line
steuert die Zeilennummer und den Dateinamen, die der Compiler bei der Ausgabe von Warnungen und Fehlern meldet.
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
ermöglicht die Angabe einer bestimmten Prüfsumme für eine generierte Programmdatenbank (PDB) zum Debuggen.
#pragma checksum "MyCode.cs" "{00000000-0000-0000-0000-000000000000}" "{0123456789A}"
Verwenden des Bedingungsattributs
Das Hinzufügen eines Conditional
Attributs aus dem System.Diagnostics
Namespace zu einer Methode ist eine saubere Methode, um zu steuern, welche Methoden in Ihren Builds aufgerufen werden und welche nicht.
#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() {...}
}
Deaktivieren und Wiederherstellen von Compiler-Warnungen
Sie können Compiler-Warnungen mit #pragma warning disable
und mit #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;
Durch Kommas getrennte Warnungsnummern sind zulässig:
#pragma warning disable CS0168, CS0219
Das CS
Präfix ist optional und kann sogar gemischt werden (dies ist jedoch keine bewährte Methode):
#pragma warning disable 0168, 0219, CS0414
Benutzerdefinierte Vorprozessoren auf Projektebene
Es ist praktisch, eine benutzerdefinierte bedingte Vorverarbeitung auf Projektebene festzulegen, wenn einige Aktionen übersprungen werden müssen, zum Beispiel für Tests.
Gehen Sie zum Projektmappen- Solution Explorer
-> Klicken Sie mit der rechten Maustaste auf das Projekt, für das Sie die Variable festlegen möchten, auf -> Properties
-> Build
-> Suchen im Feld Feld für Conditional compilation symbols
und geben Sie Ihre bedingte Variable hier ein
Code-Beispiel, das Code überspringt:
public void Init()
{
#if !IGNOREREFRESHDB
// will skip code here
db.Initialize();
#endif
}