0Pricing
C# Academy · Aula

Tipos record: fundamentos e sintaxe

Declare classes record e structs record, entenda a sintaxe posicional e compare records com classes.

Tipos record: fundamentos e sintaxe é 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 que são tipos de registro?

Os registros (introduzidos no C# 9) são tipos de referência projetados para dados imutáveis com semântica de valor. Eles geram automaticamente a igualdade com base nos valores das propriedades, um ToString() legível e oferecem mutação não destrutiva por meio de expressões with.

Sintaxe de registro posicional

A sintaxe posicional é a forma mais concisa. As propriedades, o construtor, a desconstrução e a igualdade são gerados a partir de uma única linha.

// All in one line:
public record Point(double X, double Y);
public record Person(string FirstName, string LastName, int Age);

// Generated automatically:
// - Primary constructor: new Point(1.0, 2.0)
// - Deconstruct: var (x, y) = point;
// - Equality: p1 == p2 compares X and Y values
// - ToString: "Point { X = 1, Y = 2 }"

Registros versus classes

Registros e classes diferem principalmente em sua igualdade padrão e em sua finalidade. Os registros usam igualdade estrutural (valores), enquanto as classes usam igualdade por referência (identidade).

var p1 = new Point(1, 2);
var p2 = new Point(1, 2);
var p3 = p1;

// Record: structural equality
Console.WriteLine(p1 == p2); // True — same values
Console.WriteLine(p1 == p3); // True — same values

// Compare with a class:
var c1 = new PointClass(1, 2);
var c2 = new PointClass(1, 2);
Console.WriteLine(c1 == c2); // False — different references

Estruturas de registro

O C# 10 adiciona record struct — registros que são tipos de valor. Eles têm os mesmos recursos de igualdade e ToString das classes de registro, mas são alocados na pilha como as estruturas.

// Record struct: value type, stack-allocated
public record struct Color(byte R, byte G, byte B);

var red   = new Color(255, 0, 0);
var red2  = new Color(255, 0, 0);
Console.WriteLine(red == red2); // True — value equality

// Readonly record struct: fully immutable
public readonly record struct Coord(double Lat, double Lng);

Declaração de registro padrão com corpo

Os registros podem ter um corpo completo — adicionando propriedades calculadas, métodos e validação no construtor, sem perder a igualdade e o ToString automáticos.

public record Person(string FirstName, string LastName)
{
    // Computed property
    public string FullName => $"{FirstName} {LastName}";

    // Validation in constructor
    public Person : this(FirstName, LastName)
    {
        if (string.IsNullOrWhiteSpace(FirstName))
            throw new ArgumentException("FirstName required");
    }

    // Method
    public Person WithUpperCase() =>
        this with { FirstName = FirstName.ToUpper(), LastName = LastName.ToUpper() };
}

Herança com registros

Os registros oferecem suporte à herança. Um registro derivado adiciona mais propriedades e participa das mesmas regras de igualdade — dois registros são iguais somente quando seus tipos e todos os seus valores coincidem.

public record Shape(string Color);
public record Circle(string Color, double Radius) : Shape(Color);
public record Rectangle(string Color, double Width, double Height) : Shape(Color);

var c1 = new Circle("red", 5.0);
var c2 = new Circle("red", 5.0);
var r1 = new Rectangle("red", 5.0, 3.0);

Console.WriteLine(c1 == c2); // True
Console.WriteLine(c1 == r1); // False — different types

Propriedades de registro não posicionais

Os registros não se limitam a parâmetros posicionais. Você pode combinar propriedades posicionais e manuais e usar inicializadores de propriedades para definir valores padrão.

public record Order
{
    public int Id { get; init; }
    public string CustomerName { get; init; } = "";
    public List<OrderLine> Lines { get; init; } = new();
    public DateTime CreatedAt { get; init; } = DateTime.UtcNow;
    public OrderStatus Status { get; init; } = OrderStatus.Pending;
}

// Initialization:
var order = new Order
{
    Id = 42,
    CustomerName = "Alice"
    // Other props use defaults
};

Desconstrução

Os registros posicionais geram automaticamente um método Deconstruct, permitindo desconstruí-los em atribuições e na correspondência de padrões.

public record Point(double X, double Y);

var p = new Point(3.0, 4.0);

// Deconstruction
var (x, y) = p;
Console.WriteLine($"x={x}, y={y}");

// In switch:
string Describe(Point pt) => pt switch
{
    (0, 0) => "Origin",
    (double x, 0) => $"On X-axis at {x}",
    (0, double y) => $"On Y-axis at {y}",
    var (px, py)  => $"Point ({px}, {py})"
};

Registros como DTOs

Os registros são excelentes para objetos de transferência de dados de requisições e respostas de APIs. Eles são imutáveis e serializáveis, e sua igualdade gerada automaticamente simplifica os testes.

// API request/response records
public record CreateProductRequest(
    string Name,
    decimal Price,
    int Stock);

public record ProductResponse(
    int Id,
    string Name,
    decimal Price,
    int Stock,
    DateTime CreatedAt);

// In controller:
app.MapPost("/products", (CreateProductRequest req, ProductService svc) =>
{
    var product = svc.Create(req.Name, req.Price, req.Stock);
    return Results.Created($"/products/{product.Id}",
        new ProductResponse(product.Id, product.Name,
                            product.Price, product.Stock,
                            product.CreatedAt));
});

Igualdade de registros em testes unitários

A igualdade por valor torna os registros ideais para asserções de testes unitários. Você pode comparar registros esperados e reais com == ou Assert.Equal, sem comparadores personalizados.

[Fact]
public async Task CreateOrder_ReturnsCorrectResponse()
{
    var response = await _client.PostAsJsonAsync("/orders",
        new CreateOrderRequest(CustomerId: 1, ProductId: 5, Quantity: 2));

    var order = await response.Content.ReadFromJsonAsync<OrderResponse>();

    // Simple equality check — no custom IEqualityComparer needed!
    Assert.Equal(
        new OrderResponse(Id: order!.Id, Status: "Pending", Total: 99.98m),
        order);
}

Verificação rápida

Qual semântica de igualdade os registros de C# usam por padrão?

Recapitulação: fundamentos dos tipos de registro

Principais conclusões:

  • Os registros são tipos de referência com igualdade por valor (estrutural) por padrão
  • A sintaxe posicional gera construtor, desconstrução, igualdade e ToString
  • record struct (C# 10) é uma variante de tipo de valor
  • Os registros oferecem suporte à herança — o tipo também precisa coincidir para que haja igualdade
  • São ideais para DTOs, contratos de API e asserções de testes unitários
  • Adicione propriedades calculadas e métodos em um bloco de corpo junto aos parâmetros posicionais

Perguntas Frequentes

A aula “Tipos record: fundamentos e sintaxe” é grátis?

Sim — o texto completo de “Tipos record: fundamentos e sintaxe” é 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 “Tipos record: fundamentos e sintaxe”?

Declare classes record e structs record, entenda a sintaxe posicional e compare records com classes. 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 “Tipos record: fundamentos e sintaxe”?

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. Tipos record: fundamentos e sintaxe
  2. Imutabilidade com init e with
  3. Igualdade de valores e desconstrução
  4. Records no design orientado a domínios
← Voltar para C# Academy