0Pricing
C# Academy · Aula

Migrando uma base de código para NRT

Aplique uma estratégia de migração em etapas: ative os avisos, anote APIs, corrija problemas e evite falsos positivos.

Migrando uma base de código para NRT é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.

O desafio da migração

Habilitar NRT em uma base de código existente normalmente produz centenas de avisos. Uma abordagem de mudança total de uma só vez é arriscada. Em vez disso, use uma migração em fases: habilite os avisos gradualmente, corrija-os arquivo por arquivo e nunca perca o ritmo.

Etapa 1: habilitar somente os avisos

Comece com <Nullable>warnings</Nullable> em vez de enable. Isso ativa os avisos sem tratar o código não anotado como erros — um ponto de partida seguro.

<!-- Phase 1: warnings only, no breaking change -->
<PropertyGroup>
  <Nullable>warnings</Nullable>
</PropertyGroup>

<!-- Phase 2: full enable per file as you migrate -->
<!-- Phase 3: switch to enable globally when done -->

Etapa 2: habilitar por arquivo

Adicione #nullable enable ao início de cada arquivo conforme trabalhar nele. Isso limita as alterações aos arquivos que você está editando ativamente, tornando as revisões mais fáceis de gerenciar.

#nullable enable
// Now this file has full NRT analysis

public class OrderService
{
    private readonly IOrderRepository _repo;
    // Compiler now warns about uninitialized non-nullable fields,
    // unsafe dereferences, and assignment to non-nullable

    public OrderService(IOrderRepository repo) => _repo = repo;
}

// Other files without #nullable enable are still unchecked

Categorizando os avisos

Os avisos se dividem em duas categorias: seguros para suprimir (entidades de ORM, campos injetados por DI) e bugs reais (valores que são de fato nulos e estão sendo desreferenciados). Diferencie essas categorias antes de suprimir qualquer coisa.

// Category 1: safe to suppress with null!
// EF Core navigation properties — set by EF, never null in practice
public class Order
{
    public Customer Customer { get; set; } = null!;
}

// Category 2: real bug — must fix
public string GetFullName()
{
    return FirstName + " " + LastName; // LastName was string? -- BUG!
}

Corrigindo o aviso de construtor CS8618

CS8618 é emitido quando uma propriedade não anulável não é definida no construtor. A correção preferida é exigir seu valor no construtor. Use = null! somente para valores definidos pela estrutura.

// BEFORE (CS8618)
public class Product
{
    public string Name { get; set; }   // warning
    public Category Category { get; set; } // warning
}

// AFTER — constructor required:
public class Product
{
    public string Name { get; set; }
    public Category Category { get; set; }

    public Product(string name, Category category)
    {
        Name = name;
        Category = category;
    }
}

Lidando com APIs legadas

APIs de terceiros ou legadas podem não ter anotações. Seus tipos de retorno são indiferentes à nulidade (nem anuláveis nem não anuláveis). Atribua os resultados a variáveis anuláveis para deixar isso explícito.

// Legacy API returns 'string' but might be null (oblivious type)
string? legacyResult = OldLibrary.GetValue(); // store as nullable
if (legacyResult is null) return;

// Or convert at the boundary:
string safe = OldLibrary.GetValue() ?? "";

// For third-party types, check if they have NRT annotations:
// NuGet packages often add nullable annotations in newer versions

Usando #pragma para suprimir avisos específicos

Quando um aviso é genuinamente um falso positivo e = null! parece excessivamente ruidoso, use #pragma warning disable limitado à linha específica.

// Suppress for a specific case with explanation:
#pragma warning disable CS8618 // ORM populates this via reflection
public DbSet<Product> Products { get; set; }
#pragma warning restore CS8618

// Or inline with a comment:
public DbSet<Order> Orders { get; set; } = null!; // set by EF Core

Tratando avisos de NRT como erros

Depois que todos os avisos forem corrigidos em um arquivo, adicione <WarningsAsErrors>Nullable</WarningsAsErrors> (ou use a aplicação dessa regra na integração contínua) para evitar regressões — qualquer novo problema de nulidade fará a compilação falhar.

<!-- After full migration: treat nullable warnings as build errors -->
<PropertyGroup>
  <Nullable>enable</Nullable>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  <!-- Or selectively: -->
  <!-- <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors> -->
</PropertyGroup>

Anotando APIs públicas

Quando sua biblioteca é consumida por outras pessoas, as anotações de NRT passam a fazer parte do contrato da sua API pública. Retorne T? quando o resultado puder ser nulo; retorne T quando houver garantia de que ele não será nulo.

public interface IProductService
{
    // Contract: FindById MAY return null, GetById never does
    Product? FindById(int id);
    Product  GetById(int id);  // throws if not found

    // Collection: never null (may be empty)
    IReadOnlyList<Product> GetAll();

    // String: may be empty but not null
    string GetSummary(int id);
}

Métricas e acompanhamento da migração

Acompanhe o progresso contando os arquivos com #nullable enable ou executando dotnet build 2>&1 | grep CS86 na integração contínua. Defina uma data-alvo para concluir a migração de todo o projeto.

# Count NRT warnings in current build
dotnet build 2>&1 | grep -c 'CS860[0-9]\|CS861[0-9]\|CS862[0-9]'

# List files still missing #nullable enable
grep -rL '#nullable enable' src/ --include='*.cs'

# Track in CI: fail if warning count increases
# Set a budget: warnings <= N, where N decreases each sprint

Verificação rápida

O que a atribuição = null! em uma propriedade não anulável comunica?

Recapitulação: migrando para NRT

Principais conclusões:

  • Use uma migração em fases: modo de avisos → habilitação por arquivo → habilitação global
  • Diferencie bugs reais (corrija-os) de padrões de ORM/DI (use = null!)
  • Corrija CS8618 exigindo valores nos construtores, não suprimindo o aviso
  • Atribua os resultados de APIs legadas a variáveis T? para deixar a nulidade explícita
  • Trate avisos de nulidade como erros na integração contínua para evitar regressões
  • APIs públicas anotadas tornam-se contratos claros para os consumidores

Perguntas Frequentes

A aula “Migrando uma base de código para NRT” é grátis?

Sim — o texto completo de “Migrando uma base de código para NRT” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.

O que vou aprender em “Migrando uma base de código para NRT”?

Aplique uma estratégia de migração em etapas: ative os avisos, anote APIs, corrija problemas e evite falsos positivos. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Migrando uma base de código para NRT”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Ativação e compreensão de NRT
  2. Anotações: ?, !, MaybeNull e NotNull
  3. Operadores condicionais e de coalescência de nulo
  4. Migrando uma base de código para NRT
← Voltar para C# Academy