C# - Evitando o uso do else em seu código
 Hoje veremos como podemos evitar o uso do else para escrever um código mais legível usando a linguagem C#.


De acordo com Robert C. Martin, a definição de código limpo não é muito bem definida, no entanto, os resultados do código limpo são bastante claros. Você quer que o código seja legível como um bom livro, fácil de manter e fácil de estender.

Os bugs devem ser facilmente detectáveis ou até mesmo evitados pelo design. Um código limpo manterá a produtividade alta e os custos de manutenção baixos.

Para outros desenvolvedores manterem seu código, ele deve ser extremamente fácil de ler e entender. Seu objetivo, ao escrever qualquer linha de código, deve sempre ser legibilidade. Mesmo uma linha pode confundir outro desenvolvedor o suficiente para que ele perca minutos preciosos entendendo seu código, e a culpa é sua!

Então, o que torna um código mais legível por outros desenvolvedores?

Neste artigo, veremos algumas dicas para escrever um código mais curto e legível possível de forma que elas complementam as demais diretrizes que ditam o código limpo. Cabe a você avaliar cada uma delas e verificar se a sua aplicação faz sentido para você.

Assim você deverá analisar o seu código e verificar se nos blocos de códigos que usam if-else o uso do else esta sendo feito de forma redundante. Se este for o caso esses blocos else redundantes tornam o seu código desnecessariamente longo, menos legível e o faz parecer mais complexo do que realmente é.

Evite usar else


A ideia é evitar o uso
excessivo da palavra-chave else ao escrever condicionais, e isso é possível em muitos cenários. Podemos evitar o uso do else em uma boa parte dos cenários onde ele é usado, tornando o código mais legível e mais enxuto.
 

Exemplo trivial:

 

a- Com else

public void Demo1(Teste teste)
{
    if (teste == null)
    {
        throw new ArgumentNullException(nameof(teste));
    }
    else
    {
        //Código
    }
}

b- Sem else

public void Demo2(Teste teste)
{
    if (teste == null)
        throw new ArgumentNullException(nameof(teste));

    //Código
}

Temos aqui o que é conhecido como retorno antecipado. Você deve sempre declarar claramente o que espera dos argumentos nas primeiras linhas de código.

De forma geral estamos aumentando a complexidade ao incluir qualquer novo requisito condicional usando if-else. Uma forma de evitar o uso do if-else é definir objetos de estado que pode ser feito aplicando o padrão de projeto State.

Com isso temos os seguinte benefícios:

Exemplo:
 

a- Com else

public Resultado Demo(MinhaEnum menum)
{
    if (menum == MinhaEnum.A)
    {
        //codigo1
    }
    else
    {
        //codigo2
    }
}

b- Sem else

public Resultado Demo(MinhaEnum menum)
{
    return menum switch
    {
        MinhaEnum.A => Metodo1(),
        MinhaEnum.B => Metodo2(),
        _ => throw new NotImplementedException()
    };
    Resultado Metodo1() { }
    Resultado Metodo2() { }
}

Aqui estamos alternando instruções usando o recurso da correspondência de padrões (pattern matching). Com isso temos uma visão clara do que acontece quando algum caso explícito foi passado e qual função esta tratando o caso. Além disso estamos criando um método para cada lógica separando as responsabilidades.

Como evitar o uso do else

-Usando return

Vejamos uma estrutura clássica usando if-else que avalia uma condição :

if (Condição)
{
    // 10 linhas de código
}
else
{
    // mais código
}

Em vez de usar este bloco podemos optar por usar um return e isso nos ajuda a se livrar do bloco else evitando código desnecessário.

if (Condição)
{
    // 10 linhas de código
}

 // mais código

-Usando valores padrão (default)

As instruções if-else são muito usadas para atribuir variáveis - o que não faz sentido. Você provavelmente já viu um código como este antes:

if (Condicao)
{
   numero = valor * 2;
}
else
{
   numero = 1
}

Quando você identificar um código como este, altere-o. A maneira de se livrar do bloco else é atribuir um valor padrão.

numero = 1

if (Condicao)
{
   numero = valor * 2;
}

 

O código ficou mais simples e neste caso temos duas vantagens:

  1. Ao usar um valor padrão a variável esta disponível fora da instrução if-else;

  2. Temos menos linhas de código e o código ficou mais legível;

Ainda existe uma forma de otimizar o código ainda mais usando apenas uma linha de código através do operador condicional ou ternário :
 


  numero = Condicao ? valor * 2 : 1;   
 

-Usando Guard Clauses

Uma Guard Clause ou cláusula de guarda é uma verificação de pré-condições de integridade usada para evitar erros durante a execução. Ele ajuda você a simplificar o código removendo condições de ramificação aninhadas inúteis e retornando erros significativos.

Para conseguir isso na plataforma .NET você pode usar uma biblioteca ou escrever o seu próprio código defensivo.
 

As cláusulas de guarda também são conhecidas como retornos antecipados. A ideia por trás do retorno antecipado é que você escreva funções que retornem o resultado positivo esperado no final da função.

O restante do código, na função, deve acionar o encerramento o mais rápido possível em caso de divergência com o propósito da função.


Exemplo:

public Resultado Metodo()
{
    if (!condicao)
    {
        return;
    }

    // código
}

Como alternativa podemos também inverter a cláusula de guarda :

public Resultado Metodo()
{
    if (condicao)
    {
         // código
    }  
}

 

Existem outros fatores que poderíamos abordar relacionados com este assunto mas essas dicas já vão ajudar a melhorar o seu código e torná-lo mais legível.


E estamos conversados ...

 

"Revesti-vos, pois, como eleitos de Deus, santos e amados, de entranhas de misericórdia, de benignidade, humildade, mansidão, longanimidade;"
Colossenses 3:12



Isaías 9:6
Porque um menino nos nasceu, um filho se nos deu, e o principado está sobre os seus ombros, e se chamará o seu nome: Maravilhoso, Conselheiro, Deus Forte, Pai da Eternidade, Príncipe da Paz.

Isaías 9:6

Referências:


José Carlos Macoratti