logoProgramadamente-copy_03

10 truques avançados de C# para desenvolvedores experientes

Como desenvolvedor C#, aprender técnicas mais avançadas pode ajudar você a escrever um código mais limpo, mais eficiente e inovador. Neste artigo, exploraremos algumas dez dicas avançadas de C# personalizadas para desenvolvedores mais experientes que querem forçar os limites do que é possível em C#. Esses truques podem melhorar o desempenho, a legibilidade e a manutenibilidade do seu código.

1. Aproveitando tuplas para vários valores de retorno

Tradicionalmente, para retornar múltiplos valores de um método, os desenvolvedores tinham que usar parâmetros e criar classes ou estruturas personalizadas. O C# 7, no entanto, introduziu tuplas, o que torna mais fácil e legível fazer isso.

				
					público ( int soma, int produto) Calcular( int a, int b) 
{ 
    return (a + b, a * b); 
}
				
			

Essa abordagem simplifica o tratamento de múltiplos valores de retorno e melhora a clareza do código.

2. Melhorias na correspondência de padrões

O C# 7 e versões posteriores introduziram recursos poderosos de correspondência de padrões que permitem verificações e conversões de tipos mais expressivas e concisas.

				
					public  void  ProcessoForma ( objeto forma )
 {
     if (forma is Circulo c)
    {
        Console.WriteLine( $"Circulo com raio: {c.Raio} " );
    }
     else  if (forma is Quadrado s)
    {
        Console.WriteLine( $"Quadrado com lado: {s.Lado} " );
    }
}
				
			

Essa técnica reduz a quantidade de código clichê e torna o código mais fácil de ler.

3. Usando funções locais para encapsulamento

No C# 7, funções locais foram introduzidas, o que permite que você defina métodos dentro de outro método. Essas funções são particularmente úteis para encapsular métodos auxiliares que só fazem sentido dentro de um método específico.

				
					public IEnumerable<int> Fibonacci(int n)
{
    int Fib(int term) => term <= 2 ? 1 : Fib(term - 1) + Fib(term - 2);
    return Enumerable.Range(1, n).Select(Fib);
}
				
			

Funções locais podem acessar variáveis do método envolvente, o que oferece uma maneira concisa de implementar lógica complexa.

4. Membros com corpo de expressão para código sucinto

Membros com corpo de expressão ajudam a tornar o código mais conciso, pois permitem a implementação de métodos, propriedades e outros membros em uma única linha de código.

				
					public class Pessoa
{
    public string Nome { get; set; }
    public override string ToString() => $"Nome: {Nome}";
}
				
			

Esse recurso, que foi expandido em versões recentes do C#, facilita a definição de membros de classe leves.

5. Estruturas somente leitura para tipos de dados imutáveis

Estruturas somente leitura são ideais para criar tipos de dados imutáveis. Isso significa que, uma vez que um objeto é criado, ele não pode ser alterado.

				
					public readonly struct Ponto
{
    public double A { get; }
    public double B { get; }
    
    public Ponto(double a, double b) => (A, B) = (a, b);
}
				
			

Essa construção é útil para representar tipos de dados pequenos e imutáveis, como coordenadas ou números complexos.

6. Retornos de referência e locais para otimização de desempenho

Os retornos de ref e os locais permitem que os métodos retornem referências a variáveis, em vez dos valores em si. Isso pode melhorar significativamente o desempenho para objetos grandes.

				
					public ref int BuscarPor(int[] numbers, int target)
{
    for (int i = 0; i < numbers.Length; i++)
    {
        if (numbers[i] == target)
            return ref numbers[i];
    }
    throw new IndexOutOfRangeException("Nao Encontrado");
}
				
			

Esse recurso é especialmente útil em códigos sensíveis ao desempenho que manipulam grandes estruturas de dados.

7. Usando descartes para ignorar devoluções indesejadas

Descartes são um recurso avançado que permite que os desenvolvedores ignorem parâmetros ou tuplas nos quais não estão interessados. Isso torna o código mais legível e fácil de manter.

				
					var (_, produto) = Calcular(3, 4); // Interessado apenas no produto
				
			

Isso facilita o manuseio de métodos que retornam vários valores, pois você só precisa de alguns deles.

8. Atribuição de coalescência nula para verificações de nulos simplificadas

O operador de atribuição de coalescência nula ??=simplifica o processo de atribuição de valores a variáveis quando elas podem ser nulas.

				
					List<int> numeros = null;
numeros ??= new List<int>();
numeros.Add(1);
				
			

Este operador reduz a quantidade de código necessária para garantir que um objeto seja criado antes de ser usado.

9. ValueTuple para estruturas de dados leves

ValueTuple é uma alternativa leve à estrutura de dados Tuple, que oferece uma abordagem mais eficiente em termos de memória para gerenciar coleções de valores.

				
					var pessoa = (Nome: "John", Idade: 30);
Console.WriteLine($"{pessoa.Nome} tem {pessoa.idade} anos de idade.");
				
			

ValueTuple é particularmente útil para estruturas de dados temporárias onde a sobrecarga de uma classe é desnecessária.

10. Fluxos assíncronos com IAsyncEnumerable

Os fluxos assíncronos, introduzidos no C# 8, permitem a implementação de iteração assíncrona sobre coleções que são carregadas assincronamente. Isso melhora significativamente o desempenho em aplicativos que processam dados de streaming ou são limitados por E/S.

				
					public async IAsyncEnumerable<int> PegaNumerosAsync()
{
    for (int i = 0; i < 10; i++)
    {
        await Task.Delay(100); // Simula Trabalho Assíncrono.
        yield return i;
    }
}
				
			

Referências:

Ken Fedorov: https://medium.com/@kmorpex/10-advanced-c-tricks-for-experienced-developers-26a48c6a8c9c
Facebook
Twitter
LinkedIn