C# Language
Directivas del pre procesador
Buscar..
Sintaxis
- #define [symbol] // Define un símbolo compilador.
- #undef [symbol] // Undefines un símbolo compilador.
- #warning [mensaje de advertencia] // Genera una advertencia del compilador. Útil con #if.
- #error [mensaje de error] // Genera un error del compilador. Útil con #if.
- #line [número de línea] (nombre de archivo) // Anula el número de línea del compilador (y opcionalmente el nombre del archivo de origen). Utilizado con plantillas de texto T4 .
- #pragma warning [disable | restore] [números de advertencia] // Desactiva / restaura las advertencias del compilador.
- #pragma checksum " [filename] " " [guid] " " [checksum] " // Valida el contenido de un archivo fuente.
- #region [nombre de la región] // Define una región de código plegable.
- #endregion // Finaliza un bloque de región de código.
- #if [condición] // Ejecuta el código siguiente si la condición es verdadera.
- #else // Se usa después de un #if.
- #elif [condición] // Se usa después de un #if.
- #endif // Finaliza un bloque condicional iniciado con #if.
Observaciones
Las directivas de preprocesador se utilizan normalmente para hacer que los programas de origen sean fáciles de cambiar y compilar en diferentes entornos de ejecución. Las directivas en el archivo de origen le indican al preprocesador que realice acciones específicas. Por ejemplo, el preprocesador puede reemplazar tokens en el texto, insertar el contenido de otros archivos en el archivo de origen o suprimir la compilación de parte del archivo eliminando secciones de texto. Las líneas del preprocesador se reconocen y se ejecutan antes de la expansión de macros. Por lo tanto, si una macro se expande en algo que parece un comando de preprocesador, ese comando no es reconocido por el preprocesador.
Las instrucciones del preprocesador utilizan el mismo conjunto de caracteres que las declaraciones del archivo de origen, con la excepción de que las secuencias de escape no son compatibles. El conjunto de caracteres utilizado en las instrucciones del preprocesador es el mismo que el conjunto de caracteres de ejecución. El preprocesador también reconoce valores de caracteres negativos.
Expresiones condicionales
Las expresiones condicionales ( #if
, #elif
, etc.) admiten un subconjunto limitado de operadores booleanos. Son:
-
==
y!=
. Solo se pueden usar para comprobar si el símbolo es verdadero (definido) o falso (no definido) -
&&
,||
,!
-
()
Por ejemplo:
#if !DEBUG && (SOME_SYMBOL || SOME_OTHER_SYMBOL) && RELEASE == true
Console.WriteLine("OK!");
#endif
compilaría el código que imprime "OK!" a la consola si DEBUG
no está definido, ya sea SOME_SYMBOL
o SOME_OTHER_SYMBOL
, y RELEASE
está definido.
Nota: estas sustituciones se realizan en tiempo de compilación y, por lo tanto, no están disponibles para inspección en tiempo de ejecución. El código eliminado mediante el uso de #if
no es parte de la salida del compilador.
Vea también: Directivas de preprocesador de C # en MSDN.
Expresiones condicionales
Cuando se compila lo siguiente, devolverá un valor diferente según las directivas definidas.
// 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
}
Las expresiones condicionales se utilizan normalmente para registrar información adicional para las construcciones de depuración.
void SomeFunc()
{
try
{
SomeRiskyMethod();
}
catch (ArgumentException ex)
{
#if DEBUG
log.Error("SomeFunc", ex);
#endif
HandleException(ex);
}
}
Generando advertencias y errores del compilador
Las advertencias del compilador se pueden generar usando la directiva #warning
, y los errores también se pueden generar usando la directiva #error
.
#if SOME_SYMBOL
#error This is a compiler Error.
#elif SOME_OTHER_SYMBOL
#warning This is a compiler Warning.
#endif
Definir y no definir símbolos
Un símbolo de compilador es una palabra clave que se define en tiempo de compilación y se puede verificar para ejecutar condicionalmente secciones específicas de código.
Hay tres formas de definir un símbolo compilador. Se pueden definir vía código:
#define MYSYMBOL
Se pueden definir en Visual Studio, en Propiedades del proyecto> Generar> Símbolos de compilación condicional:
(Tenga en cuenta que DEBUG
y TRACE
tienen sus propias casillas de verificación y no es necesario que se especifiquen explícitamente).
O se pueden definir en tiempo de compilación utilizando el csc.exe
/define:[name]
en el compilador de C #, csc.exe
.
También puede definir símbolos no definidos utilizando la directiva #undefine
.
El ejemplo más frecuente de esto es el símbolo DEBUG
, que Visual Studio define cuando una aplicación se compila en modo Debug (versus modo Release).
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
}
}
En el ejemplo anterior, cuando se produce un error en la lógica de negocios de la aplicación, si la aplicación se compila en modo de depuración (y se establece el símbolo DEBUG
), el error se escribirá en el registro de seguimiento y la excepción se volverá a realizar. -fruto de la depuración. Sin embargo, si la aplicación se compila en modo Release (y no se establece ningún símbolo DEBUG
), se utiliza un marco de registro para registrar el error de manera silenciosa, y se muestra un mensaje de error al usuario final.
Bloques regionales
Utilice #region
y #endregion
para definir una región de código plegable.
#region Event Handlers
public void Button_Click(object s, EventArgs e)
{
// ...
}
public void DropDown_SelectedIndexChanged(object s, EventArgs e)
{
// ...
}
#endregion
Estas directivas solo son beneficiosas cuando se utiliza un IDE que admite regiones plegables (como Visual Studio ) para editar el código.
Otras instrucciones del compilador
Línea
#line
controla el número de línea y el nombre de archivo reportados por el compilador al emitir advertencias y errores.
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
permite la especificación de una suma de comprobación específica para una base de datos de programa generada (PDB) para la depuración.
#pragma checksum "MyCode.cs" "{00000000-0000-0000-0000-000000000000}" "{0123456789A}"
Usando el atributo condicional
Agregar un atributo Conditional
desde el espacio de nombres de System.Diagnostics
a un método es una forma limpia de controlar qué métodos se llaman en las compilaciones y cuáles 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() {...}
}
Desactivación y restauración de las advertencias del compilador
Puede deshabilitar las advertencias del compilador usando #pragma warning disable
y restaurarlas usando #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;
Se permiten números de advertencia separados por comas:
#pragma warning disable CS0168, CS0219
El prefijo CS
es opcional, e incluso se puede mezclar (aunque no es una buena práctica):
#pragma warning disable 0168, 0219, CS0414
Preprocesadores personalizados a nivel de proyecto
Es conveniente establecer un preprocesamiento condicional personalizado a nivel de proyecto cuando es necesario omitir algunas acciones, por ejemplo, para las pruebas.
Vaya al Solution Explorer
-> Haga clic con el botón derecho del mouse en el proyecto en el que desea establecer la variable en -> Properties
-> Build
-> En el campo General de búsqueda Conditional compilation symbols
e ingrese su variable condicional aquí
Ejemplo de código que saltará algún código:
public void Init()
{
#if !IGNOREREFRESHDB
// will skip code here
db.Initialize();
#endif
}