C# — Operadores implícitos e explícitos
Tags: csharp, dotnet, development, tip
Published: 2023-08-11 00:27:08

Neste conteúdo, vamos falar sobre operadores implícitos e explícitos em C# e como podemos criar os nossos próprios operadores.

**Operadores explícitos**

A conversão explícita ocorre quando a conversão de um tipo de dado em outro não é possível de forma direta, sendo então necessário especificar a conversão de maneira explícita no código (cast). Esse tipo de conversão pode resultar na perda de informações ou dados truncados.

```cs
double x = 1.77;
int y = (int)x;
```

No exemplo acima, não é possível realizar a conversão de forma natural do tipo **double**para **int**, sendo necessário realizar o cast. No exemplo acima teremos perda de dados ao converter o tipo **double **para **int**.

**Operadores implícitos**

São aqueles onde o compilador possui a capacidade de converter um determinado tipo de dado em outro sem a necessidade de uma conversão explícita (cast). Na conversão implícita não há perda de dados.

```cs
int x = 2023;
double y = x;
```

No exemplo acima foi possível realizar a conversão de **x**, do tipo **int **para **double **de forma natural. Vale lembrar que números reais suportam números inteiros.

**Sobrecarga de operadores**

O C# permite a criação de operadores explícitos e implícitos, porém não é possível redefinir um operador já existente.

```cs
public static explicit operator ObjetoDestino(ObjetoOrigem origem)
{
     // lógica de conversão
}

public static implicit operator ObjetoDestino(ObjetoOrigem origem)
{
     // lógica de conversão
}
```

**Definindo um operador explícito**

Vamos utilizar como exemplo a conversão entre as unidades grama e quilograma. Abaixo temos a definição das classes e a criação do nosso operador explícito na classe Grama que possui a lógica de conversão para Quilograma.

```cs
public class Grama
{
    public int Peso { get; set; }

    public Grama(int peso)
    {
        Peso = peso;
    }

    public static explicit operator Quilograma(Grama grama)
    {
        int peso = grama.Peso / 1000;
        return new Quilograma(peso);
    }
}

public class Quilograma
{
    public int Peso { get; set; }

    public Quilograma(int peso)
    {
        Peso = peso;
    }
}

// Como usar

Grama pesoEmGrama = new Grama(2500);
Quilograma pesoEmQuilograma = (Quilograma)pesoEmGrama;
```

**Definindo um operador implícito**

Operadores de conversões implícitas podem ser utilizados, por exemplo, em cenários de conversões de DTOs ou ViewModels para classes do nosso domínio sem a utilização de ferramentas externas como por exemplo o AutoMapper. Abaixo um exemplo de conversão implícita entre nosso DTO e nossa classe de domínio.

```cs
public class PessoaDto
{
    public string Nome { get; set; }
    public int Idade { get; set; }
    public string Email { get; set; }

    public static implicit operator Pessoa(PessoaDto pessoa)
    {
        return new Pessoa(pessoa.Nome, pessoa.Idade, pessoa.Email);
    }    
}

public class Pessoa
{
    public Guid Id { get; set; }
    public string Nome { get; set; }
    public int Idade { get; set; }
    public string Email { get; set; }

    public Pessoa(string nome, int idade, string email)
    {
        Id = Guid.NewGuid();
        Nome = nome;
        Idade = idade;
        Email = email;
    }
}

// Como usar

PessoaDto pessoaDto = new PessoaDto()
{
    Email = "contato@medium.com",
    Idade = 25,
    Nome = "Fulano"
};

Pessoa pessoa = pessoaDto;
```

No exemplo acima podemos efetuar a conversão do nosso DTO em nossa classe de domínio de forma natural.

**Conclusão**

A sobrecarga de operadores implícitos e explícitos é um recurso poderoso que pode tornar nossos códigos mais expressivos e fáceis de usar, porém nada está escrito em pedra e nenhuma solução é ideal para todos os projetos. Devemos sempre analisar o cenário, como o time trabalha, além de levantar os impactos que podem surgir em sua adoção.

**Fontes**

[Operadores de conversão explícitos e implícitos definidos pelo usuário](https://learn.microsoft.com/pt-br/dotnet/csharp/language-reference/operators/user-defined-conversion-operators)