0Pricing
C# Academy · Aula

Ativação e compreensão de NRT

Ative o contexto anulável, entenda os tipos de referência anuláveis e não anuláveis e leia os avisos do compilador.

Ativação e compreensão de NRT é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 1 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 erro de um bilhão de dólares

Tony Hoare (inventor de null) chamou isso de seu “erro de um bilhão de dólares”. Em C#, qualquer tipo de referência poderia ser nulo por padrão, fazendo de NullReferenceException a falha em tempo de execução mais comum. Os tipos de referência anuláveis (NRT) corrigem isso no nível do compilador.

Habilitando o contexto de anulabilidade

Habilite NRT globalmente no arquivo do projeto ou por arquivo usando diretivas. Depois de habilitado, o compilador trata os tipos de referência como não anuláveis por padrão.

<!-- In .csproj — enable for the whole project -->
<PropertyGroup>
  <Nullable>enable</Nullable>
</PropertyGroup>

// Or per-file:
#nullable enable
// ... code with NRT warnings
#nullable disable
// ... code without NRT warnings

Tipos de referência não anuláveis e anuláveis

Com NRT habilitado: string significa que o valor nunca é nulo; string? significa que ele pode ser nulo. O compilador avisa se você atribuir nulo a um tipo não anulável ou desreferenciar um tipo anulável sem uma verificação.

#nullable enable

string nonNull = "Hello";    // OK
string? maybeNull = null;    // OK — explicitly nullable

nonNull = null;              // WARNING: CS8600
Console.WriteLine(maybeNull.Length); // WARNING: CS8602 — may be null

// Fix:
if (maybeNull is not null)
    Console.WriteLine(maybeNull.Length); // safe

Análise de fluxo

O compilador realiza análise de fluxo — acompanha o estado de nulidade por condicionais e ramificações, suprimindo avisos quando consegue provar que um valor não é nulo.

string? name = GetName();

// After null check, name is treated as non-null:
if (name is not null)
    Console.WriteLine(name.Length);  // no warning

// Same with early return:
if (name is null) return;
Console.WriteLine(name.Length);     // no warning — null was returned

// Pattern matching:
if (name is string s)
    Console.WriteLine(s.ToUpper()); // no warning

Avisos de anulabilidade: CS8600–CS8629

Principais avisos de NRT que você deve entender: CS8600 (atribuindo nulo a um tipo não anulável), CS8602 (desreferência de um valor possivelmente nulo), CS8603 (retornando nulo para um tipo não anulável), CS8618 (campo não anulável não inicializado).

#nullable enable

public class Order
{
    public string CustomerName { get; set; } // CS8618: not initialized
    public string? TrackingNumber { get; set; } // OK — nullable

    public Order(string name)
    {
        CustomerName = name; // now initialized — CS8618 gone
    }
}

string? s = GetValue();
Console.WriteLine(s.Length); // CS8602: s might be null

Inicializando campos não anuláveis

CS8618 é gerado quando um campo ou uma propriedade não anulável não é definido no construtor. Soluções: inicializá-lo na declaração, exigi-lo por meio do construtor ou usar o operador de supressão de nulo em padrões de DI/ORM.

// Option 1: Initialize in declaration
public string Name { get; set; } = "";

// Option 2: Require via constructor
public class Product
{
    public string Name { get; }
    public Product(string name) => Name = name;
}

// Option 3: null-forgiving for ORM entities
public string Name { get; set; } = null!;
// null! tells compiler "trust me, this will be set by EF Core"

Anulabilidade em tipos genéricos

Os parâmetros de tipo genérico podem ser restringidos para não anuláveis. Uma restrição where T : notnull garante que T nunca seja nulo.

// Without constraint: T could be nullable
public T? Find<T>(int id) { ... }

// With notnull: T must be a non-nullable type
public T FindRequired<T>(int id) where T : notnull
{
    var result = InternalFind<T>(id);
    return result ?? throw new KeyNotFoundException();
}

// T? is meaningful only when T is known to be non-nullable
public T? FindOrDefault<T>(int id) where T : class { ... }

Anulabilidade em interfaces e substituições

Ao implementar uma interface ou substituir um método, as anotações de anulabilidade devem corresponder. O compilador verifica se as implementações são pelo menos tão não anuláveis quanto a declaração da interface.

public interface IRepository<T>
{
    T? FindById(int id);       // may return null
    T GetOrThrow(int id);      // never null
}

// Implementation:
public class ProductRepo : IRepository<Product>
{
    public Product? FindById(int id)  => _db.Find(id);
    public Product  GetOrThrow(int id) =>
        _db.Find(id) ?? throw new KeyNotFoundException();
}

Tipos de valor anuláveis e tipos de referência anuláveis

Não confunda int? (Nullable<int> — um contêiner de tipo de valor que existia antes do C# 8) com string? (anotação NRT — válida apenas em tempo de compilação, sem sobrecarga em tempo de execução).

// Nullable value type (runtime Nullable<int>)
int? age = null;
bool hasValue = age.HasValue;
int value  = age.GetValueOrDefault();

// Nullable reference type (compile-time annotation only)
string? name = null;
// string? has NO runtime wrapper — it's just a compile-time hint
// null check is still needed at runtime
if (name is not null)
    Console.WriteLine(name.ToUpper());

Suprimindo avisos com !

O operador de supressão de nulo (!) suprime um aviso específico de anulabilidade quando você tem mais informações que o compilador. Use-o com moderação e documente por que ele é seguro.

// Use ! when you know the value cannot be null
var user = _db.Users.FirstOrDefault(u => u.Email == email);
var name = user!.Name; // user is guaranteed by business logic

// EF Core navigation properties set by the framework:
public class Order
{
    public Customer Customer { get; set; } = null!; // set by EF Core
}

Na prática: resposta de API anulável

Um encapsulador de API no qual os campos podem estar presentes ou não na resposta JSON — as anotações de anulabilidade comunicam a intenção com clareza.

#nullable enable

public class WeatherResponse
{
    public string City { get; set; } = "";     // always present
    public double Temperature { get; set; }     // always present
    public string? Description { get; set; }    // optional field
    public string? AlertMessage { get; set; }   // only when there's an alert
}

// Consumer:
var weather = await api.GetWeatherAsync("London");
Console.WriteLine(weather.City);            // safe
Console.WriteLine(weather.Description?.ToUpper() ?? "N/A"); // safe null-handling

Verificação rápida

Qual é a sobrecarga em tempo de execução dos tipos de referência anuláveis (string?) em comparação com os tipos de referência comuns (string)?

Recapitulação: habilitando e entendendo NRT

Principais conclusões:

  • Habilite globalmente com <Nullable>enable</Nullable> no .csproj
  • string = nunca nulo; string? = pode ser nulo
  • A análise de fluxo acompanha o estado de nulidade por ramificações e retornos
  • As anotações NRT existem apenas em tempo de compilação — zero sobrecarga em tempo de execução
  • CS8618: inicialize campos não anuláveis no construtor ou use = null! para ORM
  • Use ! com moderação — documente por que a supressão de nulo é segura

Perguntas Frequentes

A aula “Ativação e compreensão de NRT” é grátis?

Sim — o texto completo de “Ativação e compreensão de 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 “Ativação e compreensão de NRT”?

Ative o contexto anulável, entenda os tipos de referência anuláveis e não anuláveis e leia os avisos do compilador. 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 1 de 4.

Quanto tempo leva a aula “Ativação e compreensão de 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