Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Sugestão
Novo no desenvolvimento de software? Não vais precisar de diretivas do pré-processador imediatamente. Foca-te primeiro nos tutoriais para começar e volta aqui quando os teus projetos exigirem compilação condicional ou configuração de build.
Experiente noutra língua? Se estiveres familiarizado com #ifdef C/C++ ou compilação condicional noutras linguagens, as diretivas de pré-processador em C# funcionam de forma semelhante. Passa rapidamente até à sintaxe que precisas.
As diretivas de pré-processador C# indicam ao compilador que código deve incluir, excluir ou tratar de forma diferente quando constrói a sua aplicação. Esta orientação pode alterar o programa resultante. As diretivas do pré-processador começam sempre com # e devem aparecer numa linha própria (ignorando o espaço em branco inicial). Pode adicionar um comentário final após a diretiva. Embora a referência linguística documente todas as diretivas disponíveis, três grupos abrangem o uso quotidiano:
-
Aplicações baseadas em ficheiros (
#:) - configurar aplicações baseadas em ficheiros. -
Compilação condicional (
#if/#elif/#else/#endif) — incluir ou excluir código com base na configuração de build ou framework de destino. -
Supressão de avisos (
#pragma warning) — suprimir ou restaurar avisos específicos do compilador.
Diretivas de aplicação baseadas em ficheiros
A partir de C# 14, as aplicações baseadas em ficheiros usam duas diretivas adicionais:
-
#!— a linha shebang que permite executar o ficheiro diretamente no Unix (por exemplo,./Program.cs). Isto requer que a permissão de execução seja definida no ficheiro (chmod +x <file>). -
#:— diretivas do sistema de construção que configuram pacotes, definições do SDK e outras opções para programas de ficheiro único.
Uso #:package para adicionar um pacote NuGet. Por exemplo, a seguinte aplicação baseada em ficheiro usa o Spectre.Console pacote para renderizar saída formatada:
#!/usr/bin/env dotnet
#:package Spectre.Console@*
AnsiConsole.MarkupLine("[bold green]Hello[/] from a file-based app!");
Podes especificar uma versão exata com @, ou usar @* para puxar a versão mais recente. Adicione múltiplas #:package diretivas para incluir mais pacotes:
#:package Serilog@3.1.1
Outras #: diretivas permitem referenciar projetos, definir propriedades do MSBuild ou alterar o SDK:
#:project ../SharedLibrary/SharedLibrary.csproj
#:property PublishAot=false
#:sdk Microsoft.NET.Sdk.Web
Para a lista completa de diretivas, veja Aplicações baseadas em ficheiros e a referência da linguagem.
Compilação condicional
Use #if, #elif, #else, e #endif para incluir ou excluir código com base na definição de um símbolo. Os símbolos mais comuns são DEBUG (definidos automaticamente para builds de Debug) e símbolos de framework 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
}
O sistema de build define o símbolo DEBUG quando compilas na configuração Debug. Não precisas de o definir tu próprio. Permitir símbolos do framework como NET10_0_OR_GREATER e NET8_0_OR_GREATER permite que escrevas código que se adapta a diferentes versões do .NET em projetos de múltiplas plataformas.
Pode combinar símbolos com operadores lógicos: && (e), || (ou) e ! (não):
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
}
Utilize #define no início de um ficheiro para definir os seus próprios símbolos. Também pode definir símbolos para todo o projeto usando a DefineConstants propriedade no seu ficheiro de projeto.
Supressão de avisos
Use #pragma warning disable para suprimir avisos específicos do compilador e #pragma warning restore para os reativar. Delimite sempre a supressão da forma mais restrita possível.
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.");
}
}
Sugestão
Especifique sempre o número de aviso, como CS0168, em vez de desativar todos os avisos. Esta abordagem mantém a supressão direcionada e torna claro porque é que um aviso está a ser suprimido.