C# - Economize tempo com C#


Saiba como ganhar tempo digitando menos código usando recursos simples da linguagem C#.

Hoje veremos algums exemplos de como economizar tempo digitando menos código, e assim cometendo menos erros, usando recursos simples da linguagem C#.

Parâmetros Opcionais

Um uso muito comum da sobrecarga de métodos é definir métodos onde utilizamos parâmetros que muitas vezes não precisamos usar.

  static int Soma(int a, int b)
  {
      return a + b;
  }
  static int Soma(int a, int b, int c)
  {
      return a + b + c;
  }
  static int Soma(int a, int b, int c, int d)
  {
     return a + b + c + d;
  }
  static int Soma(int a, int b, int c = 0, int d = 0 )
  {
       return a + b + c + d;
  }
 
Temos 3 métodos com sobrecarga usando múltiplos parâmetros  Usando parâmetros opcionais

Abreviamos o método Soma() com 3 sobrecargas em um único método com parâmetro opcionais. Quando um parâmetro não for informado atribuímos ao mesmo um valor padrão.

Usando parâmetros opcionais  consolidamos os 3 métodos em um único método com economia de código.

Operador condicional Null (?.)

Algumas vezes temos que fazer o tratamento de valores null, checando explicitamente a condição null antes de poder usar um objeto, e isso pode se tornar um pesadelo e tornar o código longo e difícil de ler.
 

Nota: O operador verificar se a instância é null antes de chamar o método ou propriedade.


No trecho de código a seguir estamos fazendo uma conexão remota com um banco de dados e estamos tentando manipular alguns registros de uma tabela.

 

   if(dbConnection != null && dbConnection.Table != null && dbConnection.Table.Records != null)
   {
      Return dbConnection.Table.Records.Count;
   }


Neste tipo de cenário ás vezes precisamos realizar um monte de verificações de valores null para evitar o lançamento de exceções.

Usando o operador condicional null podemos tornar o código menor, mais elegante e mais fácil de ler:

    if(dbConnection?.Table1?.Records?)
    {
       Return dbConnection.Table.Records.Count;
    }

Outra situação muito comun é verificar se o valor de uma variável não é null antes de realizar alguma operação com a mesma:

     if (funci != null && funci.Endereco != null)
     {
           Console.WriteLine((funci.Nome) + "  " + (funci.Endereco.Residencial ?? "Sem endereço"));
     }
     Console.ReadLine();

Aqui também a utilização do operador null condicional pode economizar tempo de digitação e facilitar a leitura do código:

    Console.WriteLine((funci?.Nome) + "  " + (funci?.Endereco?.Residencial ?? "Sem endereço"));
    ReadLine();

Nota :  O operador condicional null (?.) também é conhecido como operador Elvis ou Elvis operator. (adivinha porquê?)
 

Tratamento de exeções Try/Catch

Embora seja mais indicado fazer o tratamento de erros antes que eles ocorram, existem casos onde é mais apropriado lançar uma exceção ou impedir que uma exceção lançada chegue ao usuário.

Considere o seguinte cenário :

Nossa aplicação está acessando um web service de terceiros, e , a qualquer momento, esse serviço pode ficar offline, responder de forma inesperada, etc.

Enquanto escrevemos nosso código esperando que ele funcione de uma certa maneira, precisamos cobrir nossas bases no caso do serviço se comportar de forma inesperada ou falhar.

Temos várias opções sobre como podemos lidar com isso:

1- Deixar o usuário visualizar o erro

  var resultado = (CalculaTempo)WebService.ReadToEnd();

Quando o webservice se comportar mal, nossos usuários são confrontados com uma mensagem de erro.  Se você tiver sorte, o erro foi registrado no log, mas há uma boa chance de que nada acontecesse, então você nem saberia que algo no serviço deu errado até que alguém reclamasse.

Fica evidente que essa abordagem não é melhor maneira enfrentar o problema.

2- Capturar e 'engolir' os erros

Podemos também realizar um tratamento de exceção usando try/catch onde engolimos os erros não fazendo o tratamento do bloco catch

try
  {
   var resultado = (CalculaTempo)WebService.ReadToEnd();
  }
  catch (Exception ex)
  {
 
    //não faz nada
  }

Essa abordagem é muito pior do que lançar erros ao usuário. Nessa abordagem quando algo der errado para o usuário vai parecer que tudo esta indo bem.

Isso pode causar todos tipos de problemas como fazer o usuário pensar que o pagamento de um pedido foi feito quando não foi, ou que um pedido foi enviado quando não foi.

Com certeza, fazer com que os erros não apareçam é a pior forma de fazer o tratamento de erros.

3- Fazer o tratamento de erros com try/catch

Nessa abordagem vamos fazer o tratamento de erros padrão usando o bloco try/catch.

  try
  {
     var resultado = (CalculaTempo) WebService.ReadToEnd();
  }
 catch (Exception ex)
 {
    Logger.Log (ex);
    ExibirMensagemDeErroAmigavelAoUsuario();
 }

Essa abordagem é melhor que as duas anteriores. Ela segue a prática padrão de fornecer ao usuário uma mensagem do tipo : "Algo deu errado, tente novamente mais tarde.", e, em seguida registra o erro no registro de log para poder ser analisado pelo suporte técnico.

4- Fazer o tratamento de erros específicos com try/catch

Nesta abordagem estamos fazendo um tratamento mais refinado de erros usando o bloco try/catch. 

 try
  {
     var resultado = (CalculaTempo) WebService.ReadToEnd();
  }
  catch (TimeOutException ex)
  {
    Logger.Log (ex, Severity.Medium);
    Alerta (Equipe.TI);
    ExibeDadosEmCacheAoUsuario();
  }
  Catch (InvalidCastException ex)
  {
    Logger.Log (ex, Severity.Critical);
    Alerta (Equipe.Desenvolvedores);
    ExibirErroAoUsuario();
  }
  Catch (Exception ex, Severity.High)
  {
    Logger.Log (ex);
    Alerta (Equipe..Todos);
    ExibirErroAoUsuario();
}

Essa abordagem é mais indicada para fazer o tratamento de erros.

Em todos os casos registramos o erro e fornecemos uma nível de gravidade alertando a equipe responsável fornecendo uma resposta ao usuário.

Se obtivermos um TimeOutException significa que o web servie demorou muito para responder, então logamos o erro, alertamos a equipe de TI pois podemos ter problemas na rede e exibimos ao usuário os dados do seu último acesso.

Se obtivermos um InvalidCastException, isso pode ser grave e significa que os dados que o web service forneceu não são os dados que esperamos. Neste caso nossa aplicação deixou de funcionar até que possamos ajustá-la e para isso alertamos os desenvolvedores.

Finalmente se houver qualquer outro erro alertamos todo mundo (pois não temos certeza qual o tipo de erro) e fornecermos ao usuário a mensagem padrão : "Ocorreu um problema com sua solicitação. Tente novamente mais tarde..."

Conclusão:

- Um tratamento de erro mais específico e planejado, conforme o cenário da aplicação, é sempre mais indicado;
- Sempre devemos registrar os erros em um log de erros para uma análise posterior;
- Nunca devemos ocultar ou enterrar os erros;
- Sempre devemos avisar o usuário com uma mensagem amigável quando ocorrer algum problema na aplicação;

Até o próximo artigo...

Está alguém entre vós aflito? Ore. Está alguém contente? Cante louvores. Tiago 5:13

Referências:


José Carlos Macoratti