Directivas de preprocesamiento en C#
A pesar de que C# no tenga un preprocesador de código dedicado (tal como lo tiene C), aún podemos hacer uso de algunas instrucciones que modifican el comportamiento del compilador, a estas palabras se les conoce como directivas.
Sintaxis
La sintaxis de una directiva es simple: comienza por el símbolo #
seguido inmediatamente por la instrucción para el compilador. Por ejemplo:
Instrucciones disponibles
Podemos dividir las directivas dentro estas categorías:
Definición de símbolos de compilación
Primero que nada: En C#, un símbolo de compilación es una palabra (distinta de true
o false
) que es definida al momento de compilar el programa. Normalmente es el entorno en el que desarrollamos el encargado de definir dichos símbolos, por ejemplo, en Visual Sutdio cuando ejecutamos un programa en configuración Debug, el símbolo DEBUG
es definido para nuestro código, o en Xamarin.Forms los símbolos WINDOWS
, IOS
y ANDROID
son definidos dependiendo del proyecto que estamos compilando.
Pero nosotros también podemos definirlos mediante el uso de la directiva #define [símbolo]
y borrar la definición mediante #undef [símbolo]
. Mira el siguiente código:
En este caso para el archivo quedarán definidos los símbolos HOLA
y PIZZA
, estas definiciones se hacen con una sola intención, que veremos más adelante. Hay que señalar que las definiciones deben ser las primeras instrucciones en cada archivo.
Compilación condicional
Las directivas #if
, #else
, #elif
y #endif
permiten modificar el código que el compilador toma en cuenta para la compilación, funcionan de modo similar a un if
en C#: #if [condición]
, salvo que las condiciones simplemente son si determinado símbolo está definido o no, por ejemplo:
El resultado de la ejecución es
Hola Hola o mundo y ¡pizza!
Los usos de la compilación condicional son muy variados, desde indicar que cierta porción de código únicamente se compile cuando estamos vamos a ejecutar una versión de prueba de nuestra aplicación hasta compilar distinto código fuente de acuerdo a la plataforma en la que se estará ejecutando la aplicación.
Generar errores y warnings
Podemos usar las directivas #error
y #warning
para hacer que el compilador “encuentre” errores y advertencias en nuestro código. La sintaxis es la siguiente: #error [mensaje]
y #warning [mensaje]
, por ejemplo:
Pero, ¿para qué querríamos provocar errores o warnings en nuestro código? yo creo que nadie. Sin embargo, usando la compilación condicional podemos “impedir” que el código se compile a menos que alguna configuración se cumpla, es por eso que normalmente estas directivas vienen rodeadas de #if
, #endif
o #elif
:
Supresión de warnings
Del mismo modo que podemos crear warnings, también podemos instruir al compilador a que ignore algunas de estas mediante el uso de la directiva #pragma warning disable ([identificador de advertencias])
.
Nunca ha sido bueno ignorar las advertencias en nuestro código … sin embargo se me ocurren dos escenarios principales:
- Cuando accederemos al código de nuestro programa mediante reflexión y el compilador nos advierte que no estamos usando determinada propiedad o método.
- Cuando estamos implementando una interfaz y nuestro código únicamente llama a algunos métodos de la interfaz
Cuando deshabilitamos el reconocimiento de advertencias con la directiva anterior, el efecto permanece hasta el fin del archivo, pero podemos deshabilitar dicho efecto usando la directiva #pragma warning restore ([identificador de advertencias])
. Tomemos como ejemplo esta porción de código que como te podrás imaginar, provoca unas cuantas advertencias.
Podemos deshabilitar las advertencias una por una:
Varias a la vez:
O simplemente todas a la vez:
Organización de código
Estas son es seguramente las directivas con las que más frecuentemente te has encontrado, y es que su uso es mucho más común que las otras, su finalidad es agrupar físicamente bloques de código dentro de nuestro archivo fuente, además de que algunos IDE permiten colapsar el texto entre ella. Es importante decir que su inclusión no modifica el comportamiento del compilador.
Por ejemplo:
Que en Visual Studio se ve así:
Para finalizar
Como puedes ver, las directivas nos pueden ayudar a personalizar nuestro código a partir de condiciones dictadas antes de la compilación del mismo, o a “forzar” que ciertas condiciones se cumplan para que siquiera compile. También nos ayudan a organizar nuestro código en bloques físicos dentro del archivo fuente.