DEV Community

José Robson
José Robson

Posted on

3 1

Por que usar `record` para construir DTOs em C#?

Data Transfer Objects (DTOs) são um padrão de design amplamente utilizado para transferir dados entre diferentes partes de um sistema. Eles são usados para encapsular dados e simplificar a comunicação entre camadas de uma aplicação ou entre sistemas diferentes. DTOs são especialmente úteis para reduzir a quantidade de dados enviados, garantir a integridade dos dados e facilitar a manutenção do código.

Ao construir DTOs em C#, a escolha entre record e class pode impactar significativamente a clareza e a segurança do código. Embora os exemplos a seguir usem um sistema bancário, os benefícios dos records se aplicam a qualquer tipo de sistema. Vamos explorar três razões para optar por records ao construir DTOs, ilustradas com exemplos práticos:

1️⃣ Comparação por Valor:

Em qualquer sistema, comparar objetos com base em seus valores é uma necessidade comum. Com records, a comparação por valor é feita automaticamente, o que reduz a necessidade de código adicional e diminui o risco de erros.

Exemplo com class:

public class TransacaoDto
{
    public string IdTransacao { get; }
    public decimal Valor { get; }
    public DateTime Data { get; }

    public TransacaoDto(string idTransacao, decimal valor, DateTime data)
    {
        IdTransacao = idTransacao;
        Valor = valor;
        Data = data;
    }

    public override bool Equals(object? obj)
    {
        if (obj is TransacaoDto transacao)
        {
            return IdTransacao == transacao.IdTransacao &&
                   Valor == transacao.Valor &&
                   Data == transacao.Data;
        }
        return false;
    }

    public override int GetHashCode() => HashCode.Combine(IdTransacao, Valor, Data);
}
Enter fullscreen mode Exit fullscreen mode

Exemplo com record:

public record TransacaoDto(string IdTransacao, decimal Valor, DateTime Data);
Enter fullscreen mode Exit fullscreen mode

Por que record é melhor?

Os records já implementam a comparação por valor automaticamente, simplificando o código e garantindo que a comparação de dados seja feita de maneira correta e eficiente.

2️⃣ Imutabilidade por Padrão:

DTOs frequentemente representam dados que não devem ser alterados após sua criação. records são imutáveis por padrão, o que garante que os dados permaneçam consistentes e seguros.

Exemplo com class:

public class ContaDto
{
    public string NumeroConta { get; }
    public string Titular { get; }
    public decimal Saldo { get; private set; }

    public ContaDto(string numeroConta, string titular, decimal saldo)
    {
        NumeroConta = numeroConta;
        Titular = titular;
        Saldo = saldo;
    }

    // Para garantir imutabilidade, não deve haver métodos para modificar as propriedades
}
Enter fullscreen mode Exit fullscreen mode

Exemplo com record:

public record ContaDto(string NumeroConta, string Titular, decimal Saldo);
Enter fullscreen mode Exit fullscreen mode

Por que record é melhor?

Com records, a imutabilidade é garantida sem a necessidade de lógica adicional, tornando o código mais seguro e menos propenso a erros.

3️⃣ Sintaxe Concisa e Leitura Limpa:

Definir DTOs com records resulta em um código mais direto e fácil de ler, o que é benéfico para a manutenção e a clareza do código.

Exemplo com class:

public class ClienteDto
{
    public string Id { get; }
    public string Nome { get; }
    public string Email { get; }

    public ClienteDto(string id, string nome, string email)
    {
        Id = id;
        Nome = nome;
        Email = email;
    }
}
Enter fullscreen mode Exit fullscreen mode

Exemplo com record:

public record ClienteDto(string Id, string Nome, string Email);
Enter fullscreen mode Exit fullscreen mode

Por que record é melhor?

A sintaxe dos records é mais concisa e direta, o que reduz a verbosidade do código e melhora a legibilidade.

4️⃣ Desconstrução:

A desconstrução permite extrair as propriedades de um record diretamente em variáveis, tornando o acesso aos dados mais fácil e direto.

Exemplo com class:

public class TransacaoDto
{
    public string IdTransacao { get; }
    public decimal Valor { get; }
    public DateTime Data { get; }

    public TransacaoDto(string idTransacao, decimal valor, DateTime data)
    {
        IdTransacao = idTransacao;
        Valor = valor;
        Data = data;
    }

    public void Deconstruct(out string idTransacao, out decimal valor, out DateTime data)
    {
        idTransacao = IdTransacao;
        valor = Valor;
        data = Data;
    }
}

var transacao = new TransacaoDto("TX123", 1000.00m, DateTime.UtcNow);
transacao.Deconstruct(out var id, out var valor, out var data);
Enter fullscreen mode Exit fullscreen mode

Exemplo com record:

public record TransacaoDto(string IdTransacao, decimal Valor, DateTime Data);

var transacao = new TransacaoDto("TX123", 1000.00m, DateTime.UtcNow);
var (id, valor, data) = transacao;
Enter fullscreen mode Exit fullscreen mode

Por que record é melhor?

A desconstrução é suportada nativamente em records, tornando o código mais limpo e simples de usar.


Conclusão: Independentemente do tipo de sistema que você está desenvolvendo, os records oferecem vantagens significativas sobre as classes para construir DTOs. Com comparação por valor automática, imutabilidade por padrão, sintaxe concisa e suporte à desconstrução, records ajudam a escrever código mais limpo, seguro e eficiente.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay