Compartir a través de


Directivas de preprocesador

Sugerencia

¿No está familiarizado con el desarrollo de software? No necesitará directivas de preprocesador inmediatamente. Concéntrese primero en los tutoriales de inicio y vuelva aquí cuando sus proyectos requieran compilación condicional o configuración de compilación.

¿Competente en otro idioma? Si está familiarizado con #ifdef en C/C++ o compilación condicional en otros lenguajes, las directivas de preprocesador de C# funcionan de forma similar. Avance rápidamente a la sintaxis que necesita.

Las directivas de preprocesador de C# indican al compilador qué código incluir, excluir o tratar de forma diferente cuando compila la aplicación. Esta guía puede cambiar el programa resultante. Las directivas de preprocesador siempre comienzan por # y deben aparecer en su propia línea (ignorando el espacio en blanco inicial). Puede agregar un comentario final después de la directiva . Aunque la referencia de idioma documenta todas las directivas disponibles, tres grupos cubren el uso diario:

  • Aplicaciones basadas en archivos (#:): configure aplicaciones basadas en archivos.
  • Compilación condicional (#if / #elif / #else / #endif): incluya o excluya el código en función de la configuración de compilación o el marco de destino.
  • Supresión de advertencias (#pragma warning): supresión o restauración de advertencias específicas del compilador.

Directivas de aplicación basadas en archivos

A partir de C# 14, las aplicaciones basadas en archivos usan dos directivas adicionales:

  • #! : la línea shebang que permite ejecutar el archivo directamente en Unix (por ejemplo, ./Program.cs). Esto requiere que el permiso de ejecución se establezca en el archivo (chmod +x <file>).
  • #: : directivas del sistema de compilación que configuran paquetes, opciones de SDK y otras opciones para programas de un solo archivo.

Use #:package para agregar un paquete NuGet. Por ejemplo, la siguiente aplicación basada en archivos usa el Spectre.Console paquete para representar la salida estilizada.

#!/usr/bin/env dotnet
#:package Spectre.Console@*

AnsiConsole.MarkupLine("[bold green]Hello[/] from a file-based app!");

Puede especificar una versión exacta con @o usar @* para extraer la versión más reciente. Agregue varias #:package directivas para incluir más paquetes:

#:package Serilog@3.1.1

Otras #: directivas permiten hacer referencia a proyectos, establecer propiedades de MSBuild o cambiar el SDK:

#:project ../SharedLibrary/SharedLibrary.csproj
#:property PublishAot=false
#:sdk Microsoft.NET.Sdk.Web

Para obtener la lista completa de directivas, consulte Aplicaciones basadas en archivos y la referencia de idioma.

Compilación condicional

Use #if, #elif, #elsey #endif para incluir o excluir código en función de si se define un símbolo. Los símbolos más comunes son DEBUG (se establecen automáticamente para compilaciones de depuración) y símbolos de marco de destino como NET10_0_OR_GREATER:

static void ConfigureLogging()
{
#if DEBUG
    Console.WriteLine("Debug logging enabled — verbose output active.");
#else
    Console.WriteLine("Release logging — errors only.");
#endif
}

El sistema de compilación define el símbolo DEBUG cuando se compila en la configuración de depuración. No es necesario definirlo usted mismo. Los símbolos del marco de destino, como NET10_0_OR_GREATER y NET8_0_OR_GREATER permiten escribir código que se adapte a diferentes versiones de .NET en proyectos de varios destinos.

Puede combinar símbolos con operadores lógicos: && (y), || (o) y ! (no):

static void ShowPlatformInfo()
{
#if NET10_0_OR_GREATER
    Console.WriteLine("Running on .NET 10 or later.");
#elif NET8_0_OR_GREATER
    Console.WriteLine("Running on .NET 8 or 9.");
#else
    Console.WriteLine("Running on an older .NET version.");
#endif
}

Use #define en la parte superior de un archivo para definir sus propios símbolos. También puede definir símbolos para todo el proyecto mediante la DefineConstants propiedad del archivo del proyecto.

Supresión de advertencias

Use #pragma warning disable para suprimir advertencias específicas del compilador y #pragma warning restore volver a habilitarlas. Establezca siempre el ámbito de la supresión lo más estrechamente posible:

    static void ProcessData()
    {
        try
        {
            // Some operation that might fail
            var data = File.ReadAllText("config.json");
            Console.WriteLine($"Config loaded: {data.Length} characters");
        }
#pragma warning disable CS0168 // Variable is declared but never used
        catch (FileNotFoundException ex)
#pragma warning restore CS0168
        {
            // Fall back to defaults — the exception details aren't needed here
            Console.WriteLine("Config file not found, using defaults.");
        }
    }

Sugerencia

Especifique siempre el número de advertencia, como CS0168, en lugar de deshabilitar todas las advertencias. Este enfoque mantiene la supresión dirigida y deja claro por qué se suprime una advertencia.