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

José Robson - Aug 24 - - Dev Community

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.

.
Terabox Video Player