viernes, 17 de julio de 2015

Directivas de Preprocesador en C#

Índice

0. Introducción
1. Directivas de Preprocesador
2. Atributos Condicionales
3. Uso de Advertencias con #pragma
4. Más Acerca de Directivas de Preprocesador
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

Pasamos en esta ocasión a estudiar las directivas de preprocesador. Con estas directivas podremos suplir información adicional al compilador para modificar el comportamiento de compilación. Nos detendremos a observar cómo las directivas de preprocesador nos facilitan determinar recursos disponibles en la plataforma adyacente y de esta manera usar APIs o bibliotecas de clases sólo disponibles en esa plataforma. Escribiremos un par de ejemplos de código C# para demostrar su declaración y uso.

1. Directivas de Preprocesador

En C# contamos con varias directivas de preprocesador que nos son útil para instruir al compilador con información adicional. Esta información alterará la forma en que se compilará la fuente C# dependiendo de la disposición de directivas en las regiones de código del archivo fuente.

Esta son las directivas de preprocesador disponibles en C# [2]:
  • #define
  • #undef
  • #if
  • #elif
  • #else
  • #endif
  • #warning
  • #error
  • #line
  • #region
  • #endregion
  • #pragma
  • #pragma warning
  • #pragma checksum
Podemos tomar, por ejemplo, las directivas #define, #undef, #if, #endif para escribir el siguiente código C#:

Notemos en la línea 3 donde hemos definido el símbolo DEPURAR para marcar determinadas regiones de código sólo compilables si este símbolo está definido. Lo anterior lo logramos con el uso de la directiva #if.


Por otro lado, #undef RASTREAR removemos la definición de RASTREAR. Esta instrucción evita que la instrucción de la línea 20 se compile.

Compilación:


  1. csc /target:exe UsoDirectivas.cs

Ejecución assembly:


  1. .\UsoDirectivas.exe

> Prueba de ejecución: http://ideone.com/YCf3xl

> Prueba de ejecución:
Ejecución assembly UsoDirectivas.exe
Figura 1. Ejecución assembly UsoDirectivas.exe.

También es posible pasar una definición de directiva desde el compilador C# de línea de comandos:


Asumamos que no tenemos definida la directiva DEPURAR en la línea 3, entonces podemos utilizar está versión de compilación con el uso del argumento /define:


  1. csc /target:exe /define:DEPURAR UsoDirectivas.cs


En el código de ejemplo anterior, usamos la directiva #if  para evaluar si el símbolo DEPURAR está definido: aquí hemos usado una sentencia simple, sin embargo podemos usar los operadores lógicos ||, &&, y ! para efectuar las operaciones OR, AND, NOT, respectivamente, para crear expresiones booleanas que involucren múltiples símbolos:

#if MODO_PRUEBA && !DEPURAR


En la Tabla 1 [1] se describen varias expresiones de directivas junto con su acción:
Expresiones con directivas de preprocesador
Tabla 1. Expresiones con directivas de preprocesador.

2. Atributos Condicionales

Un elemento de programa (e.g., método, propiedad) marcado con el atributo Conditional [3] indica al compilador efectuar la compilación de este elemento siempre y cuando un símbolo haya sido definido.


Veamos el siguiente programa C# de uso del atributo Conditional:

Archivo C# Plataforma.cs [Enlace alternativo][Enlace alternativo]:

Con el atributo Conditional y parámetro DEBUG:

[Conditional("DEBUG")]

estamos declarando que esté método será ejecutado siempre y cuando el símbolo DEBUG haya sido definido.


Para que el método esté disponible en tiempo de ejecución, debemos compilar el programa Plataforma.cs así:


  1. csc /target:exe /define:win8;DEBUG UnicaInstanciaAplicacion.cs


Cuando ejecutemos el assembly resultante obtendremos el siguiente resultado en la salida estándar:
Ejecución assembly Plataforma.exe
Figura 2. Ejecución assembly Plataforma.exe.

3. Uso de Advertencias con #pragma

Con al directiva #pragma instruimos al compilador a ser caso omiso de advertencias en un proceso de compilación común.

Supongamos que tenemos la siguiente clase:

public class PruebaPragma
{
public static void Main()
{ }

#pragma warning disable 414
public static string Mensaje = "Blog xCSw";
#pragma warning restore 414
}

Con el uso de #pragma indicamos, en este caso, al compilador obviar el mensaje de advertencia CS0168 [4].

4. Más Acerca de Directivas de Preprocesador

En la receta R1-6 Inclusión de Código Modo Selectivo en Tiempo de Compilación podremos encontrar explicaciones extra sobre el uso de directivas de preprocesador en C#.

5. Conclusiones

Comprender el uso y declaración de directivas de preprocesador en código C#, como hemos observado, nos permite modificar con información extra el comportamiento del proceso de compilación. Esto nos puede ser de utilidad cuando, por ejemplo, deseemos validar la plataforma adyacente sobre la que se ejecutará la aplicación y de ese modo recurrir al uso de las librerías diseñadas o únicamente disponibles en esa misma plataforma.


El próximo artículo C# será el último de la serie de Avanzados en C#: Documentación XML.

6. Glosario

  • API
  • Atributo
  • Compilación
  • Compilador
  • Directiva
  • Preprocesador

7. Literatura & Enlaces

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: C# Preprocessor Directives - https://msdn.microsoft.com/en-us/library/ed8yd1ha.aspx?f=255&MSPPError=-2147217396
[3]: ConditionalAttribute Class (System.Diagnostics) - https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx
[4]: Compiler Warning (level 3) CS0168 - https://msdn.microsoft.com/en-us/library/tf85t6e4(v=vs.90).aspx
[5]: R1-6 Inclusión de Código Modo Selectivo en Tiempo de Compilación - http://ortizol.blogspot.com/2013/10/r1-6-inclusion-de-codigo-modo-selectivo.html


J

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.