Quatro decisões que não são a mesma versão
C# é a linguagem; o SDK fornece ferramentas para construir projetos; o framework de destino define o contrato de APIs; o runtime executa a aplicação publicada. Este percurso usa C# 14 e .NET 10 como base explícita. Num projeto, net10.0 é um TFM e não o número completo de um SDK. global.json pode controlar a seleção do SDK sem reescrever automaticamente TargetFramework.
A versão de linguagem normalmente acompanha o destino suportado pelo SDK, mas não deves concluir que mudar apenas LangVersion instala ferramentas ou acrescenta APIs de runtime. Ao receber um erro, regista em que fase surgiu: seleção de ferramentas, restore, compilação, publicação ou arranque.
Uma mensagem sobre SDK ausente pede evidência diferente de uma exceção lançada pelo programa depois de arrancar.
Inventariar ferramentas no contexto certo
dotnet --list-sdks apresenta os SDKs instalados visíveis no contexto da arquitetura invocada; --list-runtimes apresenta os runtimes. Já --version indica o SDK selecionado para os comandos nesse contexto. O diretório de trabalho interessa: o CLI procura global.json a partir dele e nos diretórios ascendentes.
Não compares resultados obtidos em pastas diferentes sem registar essa diferença. Um ficheiro que fixa version 10.0.100 e rollForward disable exige a versão exata; encontrar apenas 10.0.101 não satisfaz a política. Uma equipa pode escolher outra política, mas deve documentá-la e controlar atualizações. global.json não é um instalador e não deve ser confundido com o ficheiro runtimeconfig da aplicação.
Instalar ferramentas na máquina de desenvolvimento também não prova que estejam disponíveis num agente CI separado.
Restaurar o grafo e controlar alterações
O restore resolve as dependências do projeto, incluindo as transitivas. NuGet produz obj/project.assets.json, que fornece ao SDK informação para a compilação. Se estiver ausente num checkout limpo, não o substituas por um JSON vazio: verifica o restore e a primeira falha que o impediu.
Para uma aplicação com dependências aprovadas, packages.lock.json regista o grafo. Um restore normal pode atualizá-lo quando os inputs mudam; a mera presença do ficheiro não proíbe alterações. Em locked mode, uma alteração incompatível com o grafo fixado deve fazer a operação falhar.
A atualização deliberada passa por rever dependências e o novo lock antes de os aceitar. O SDK também pode influenciar referências implícitas. Conservar SDK e grafo ajuda a controlar inputs, mas não prova igualdade de todos os bytes, serviços externos ou resultados de execução.
O projeto inclui itens por convenção
Num projeto SDK-style, muitos ficheiros C# já entram no conjunto Compile por convenção. Acrescentar Include para o mesmo ficheiro sem mudar os defaults pode produzir NETSDK1022. Se queres manter a convenção, retira a entrada redundante e conserva o ficheiro.
Se tens uma lista inteiramente explícita, a política precisa de desligar a inclusão predefinida correspondente. É uma decisão sobre itens do projeto, não sobre o nome de uma classe. Para um ficheiro None já incluído, Update altera os seus metadados sem o adicionar novamente.
Distingue ainda output de publish: CopyToOutputDirectory pode colocar um ficheiro junto do build local, enquanto CopyToPublishDirectory Never o exclui da cópia para publicação. A evidência relevante para a entrega é o conteúdo do artefacto que será distribuído, não apenas o que existe no repositório.
Escolher o contrato de entrega
Uma publicação framework-dependent usa um runtime compatível disponível no destino. O modo self-contained inclui os ficheiros .NET necessários, mas continua associado à plataforma e às dependências nativas do sistema. Usa opções explícitas quando comparas os dois modos.
O RID linux-x64 descreve o destino; não faz --self-contained false deixar de precisar de runtime. Incluir uma cópia do runtime também transfere responsabilidade de manutenção: atualizar um runtime global separado não atualiza automaticamente a cópia distribuída com a aplicação.
Um arranque aceite precisa de considerar configuração, arquitetura, ficheiros e permissões requeridos. Não transformes a existência de um executável num certificado de compatibilidade universal. Para um incidente, guarda a identidade do pacote entregue e compara-a com a que foi aprovada; diagnosticar outro build pode conduzir a uma conclusão irrelevante.
Avisos de trimming exigem interpretação
O trimming remove código considerado desnecessário para reduzir a publicação. Alguns padrões de reflexão dependem de tipos ou membros que a análise estática não consegue determinar. Um aviso sobre esse caminho identifica uma obrigação de investigação; suprimi-lo não declara quais os membros que precisam de sobreviver.
Quando os tipos são conhecidos, requisitos de preservação apropriados podem tornar o desenho analisável. Noutros casos, é preferível tornar a seleção explícita, usar geração adequada ou optar por uma publicação sem essa redução. Não concluas que toda a reflexão é inválida nem que qualquer compilação bem-sucedida prova compatibilidade após trimming.
A decisão deve relacionar o aviso com os caminhos utilizados pela aplicação e com a evidência do artefacto produzido. Estes conceitos explicam diagnósticos; as perguntas pedem interpretação e escolha, sem executar código.
Leitura guiada: entregar apenas a configuração necessária
O projeto ilustrado já contém Program.cs, rules.json e notes.local.json. Os ficheiros JSON são itens None incluídos pelas convenções do SDK. rules.json faz parte da configuração necessária no destino; notes.local.json contém apontamentos locais que não integram o produto.
Update fixa políticas distintas sem duplicar os itens. Para uma pasta de publicação nova e sem passos de cópia adicionais, rules.json é elegível para cópia e notes.local.json fica excluído. EnableDefaultCompileItems não foi desligado: não é necessário acrescentar Program.cs com Include.
Este XML não fixa o SDK completo, não inclui por si um runtime e não garante o conteúdo semântico de rules.json. A revisão deve verificar o contrato do projeto e o inventário do pacote. Nas avaliações, lê o XML e seleciona a explicação compatível com os factos apresentados.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Update="rules.json"
CopyToOutputDirectory="PreserveNewest"
CopyToPublishDirectory="PreserveNewest" />
<None Update="notes.local.json"
CopyToOutputDirectory="Never"
CopyToPublishDirectory="Never" />
</ItemGroup>
</Project>O build local conter rules.json não basta: o contrato deve incluí-lo na publicação, conservando fora dela os apontamentos locais.
Armadilhas comuns
Confundir TFM com SDK; fabricar project.assets.json; tratar a presença do lock como locked mode; duplicar Compile; entregar output como se fosse publish; suprimir avisos sem resolver os requisitos.
Tópicos relacionados: Exceções, recursos e ficheiros · Decimais, tempo e contratos de dados · Tarefas assíncronas e cancelamento
Diagnostica a fase certa com o SDK, o grafo e o artefacto realmente usados. Compilar, publicar e executar são evidências diferentes.
Referência: SDK selection with global.json · C# 14 / .NET 10; no preview features