visual variable test tag studio ifdebug development define debug check c#

variable - tag debug c#



¿Cómo configuro una variable de compilación condicional? (3)

Abre las propiedades de tu proyecto y mira la página de compilación. Hay una caja llamada símbolos de compilación condicional.

En C / C ++ puedes definir macros en código como este:

#define OLD_WAY 1

Aunque nunca lo he hecho, asumo que lo mismo está disponible en C #. Más al punto, en C / C ++ es posible hacer una lógica de compilación condicional haciendo algo como esto:

#if OLD_WAY == 1 int i = 0; #else int i = 1; #endif

OK, así que todo esto es genial y todo eso. Y nuevamente, asumo que tal lógica es posible dentro de C #. Lo que me gustaría saber es, ¿cómo defino constantes en el nivel del proyecto, de modo que pueda poner en una lógica que me permita compilar condicionalmente un bloque de código si defino la constante de una manera u otro bloque de código? ¿Si no lo defino así? Supongo que se hace en algún lugar de las propiedades del proyecto, pero ¿cómo y dónde lo defino?


El compilador c # csc.exe y el lenguaje C # en sí no exponen ninguna constante predefinida para la compilación condicional . VisualStudio solo agrega los valores DEBUG y TRACE , que se pueden configurar a través del IDE. El IDE también le permite agregar sus propios símbolos arbitrarios, pero dado que estos son esencialmente valores fijos (invariantes), la capacidad es de uso limitado.

Se pueden configurar opciones personalizadas más potentes editando manualmente el archivo de proyecto .csproj . Puede configurar las conditions aquí para propagar selectivamente los símbolos de compilación condicional en C # en función de la gran cantidad de información de configuración y entorno disponible en MSBuild (vea here y here , pero en principio, no puede haber una lista completa, ya que los diferentes componentes contribuyen arbitrariamente con los metadatos ad-hoc ).

Consideremos un ejemplo de trabajo. Un caso en el que es útil compilar de forma condicional es si desea escribir código que se adapte a las herramientas que se descubran durante la compilación. De esta manera, puede explotar las últimas características de lenguaje sin dejar de conservar la capacidad de compilar en máquinas con herramientas más antiguas que, como se esperaba, rechazaría la sintaxis y / o palabras clave ajenas. Para el caso particular de C # 7.0 en vs2017 podemos modificar el .csproj siguiente manera:

Archivo .csproj (extracto):

También puede identificar cada uno de los compiladores de C # más antiguos, degradándose con gracia en el camino. Lo mismo ocurre con la detección de la versión de .NET Framework (a menudo solicitada en [1] [2] [3] [4] ) y cualquier otra condición ambiental de compilación. Estos se dejan como ejercicios para el lector, pero en caso de que quiera copiar / pegar las líneas resaltadas desde arriba, aquí está la versión de texto. Como una actualización de la captura de pantalla, agregué comillas simples a la expresión condicional aquí (aunque todo parece funcionar sin ellas)

<DefineConstants Condition="''$(VisualStudioVersion)''==''15''">CSHARP7</DefineConstants> <!-- ... --> <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants> <!-- ... --> <DefineConstants>TRACE;$(DefineConstants)</DefineConstants>

De todos modos, de esta manera, ahora puede escribir código C # condicional usando #if… #elif… #else… #endif . Continuando con el caso de ejemplo, el siguiente código utiliza la nueva sintaxis de la tupla (solo disponible en C # 7) para intercambiar elementos de la matriz. Por cierto, la versión de la tupla no solo es más concisa y / o elegante; también produce un excelente código IL:

#if CSHARP7 (rg[i], rg[j]) = (rg[j], rg[i]); // swap elements: tuple syntax #else var t = rg[i]; // swap elements: clunky rg[i] = rg[j]; rg[j] = t; #endif

Tenga en cuenta que el IDE de Visual Studio procesa correctamente sus personalizaciones .csproj manuales en todos los aspectos. Dado el .csproj que mostré anteriormente, el editor de código IDE reconoce y evalúa correctamente la compilación condicional para los propósitos de IntelliSense , refactoring , "atenuación" de bloques de código inactivos, etc.

También mencioné que MSBuild tiene un tesoro de información disponible, de los cuales $(VisualStudioVersion) fue solo un ejemplo. Desafortunadamente, no es fácil descubrir qué valores están disponibles y qué valores podrían tener en el momento de la creación. Un truco es colocar temporalmente un proyecto de C++ en su solución de Visual Studio (si aún no tiene uno) junto con su proyecto de C #. Si hace clic con el botón derecho en las propiedades del proyecto para este .vcxproj y luego observa (por ejemplo) "Directorios de inclusión adicionales" en la página C/C++ , aparecerá un menú desplegable en el extremo derecho cuando haga clic para editar:

Obtendrá un cuadro de diálogo con un botón de "Macros" en el que puede hacer clic para obtener una lista de todas las variables de MSBuild disponibles más sus valores esperados según la plataforma y la configuración que están actualmente seleccionadas en el IDE. No pase por alto los campos de well-known-item-metadata (con el prefijo % ) al final de la lista.

Puede obtener una idea de la cantidad de cosas que hay aquí del tamaño del pulgar de la barra de desplazamiento en esta captura de pantalla. (Están en orden alfabético, acabo de desplazarme a esta parte de la sección ''P'' porque tenía información personal mínima). Sin embargo, es importante tener en cuenta que tanto las variables (disponibles) como sus valores evolucionan a lo largo del tiempo de la compilación, por lo que puede encontrar elementos en esta lista que no estén disponibles para su .csproj en el momento en que se procesan .


En C # puede hacer #define pero no puede usar valores en ellos como puede hacerlo en C ++.
Cada definición puede tener 2 estados: definido o no definido

En las propiedades del proyecto en Construir puede establecer las definiciones que deben definirse.
Todo lo que especifique aquí se definirá en todos los archivos de su proyecto.

Entonces, por ejemplo, puedo definir 2 símbolos de compilación condicional en este campo como:
MY_DEFINE1, MY_DEFINE2

Luego en mi código puedo hacer cosas como esta:

#if MY_DEFINE1 //do something conditionally #endif #if MY_DEFINE2 //do something else conditionally #endif

Alternativamente, puede hacer sus definiciones por archivo, pero a diferencia de C ++, deben estar en la parte superior de su archivo.

En la parte superior de su archivo puede utilizar:

#define MY_DEFINE2

o puede, en la parte superior de su archivo, usar:

#undef MY_DEFINE2

Este último lo haría si configurara un símbolo de compilación condicional y lo deseara en todos los archivos excepto tal vez en uno.