Métodos de Extensão em C#: Estendendo Funcionalidades de Tipos Existentes

Os métodos em C# podem ser categorizados da seguinte forma:

  • Métodos estáticos (declarados com o modificador static)
  • Métodos de instância
  • Métodos virtuais (declarados com o modificador virtual)
  • Métodos sobrescritos (declarados com o modificador override)
  • Métodos selados (declarados com o modificador sealed)
  • Métodos abstratos (declarados com o modificador abstract)
  • Métodos externos (declarados com o modificador extern)
  • Métodos parciais (declarados com o modificador partial)
  • Métodos de extensão (o pirmeiro parâmetro usa o modificador this)

Métodos de extensão: são na realidade métodos estáticos declarados em classses estáticas não aninhadas e não genéricas, criados para adicionar funcionalidades especiais a tipos existentes.

Exemplo: A classe nativa string não possui um método ToInt32() por padrão, mas podemos criar um método de extensão para isso

// Primeiro passo: Criar uma classe estática de nível superior
// Convenção de nomenclatura: TipoAlvo + Extensao -- por exemplo: StringExtensao
static class UtilitariosConversao
{
    // Segundo passo: Criar um método estático com o primeiro parâmetro usando 'this'
    
    /// <summary>
    /// Fornece um método de extensão para converter string em inteiro
    /// </summary>
    /// <param name="entradaTexto">Valor string a ser convertido</param>
    /// <returns>Valor inteiro após conversão bem-sucedida</returns>
    public static int ConverterParaInt(this string entradaTexto)
    {
        int valorResultado = 0;
        if (int.TryParse(entradaTexto, out valorResultado))
        {
            return valorResultado;
        }
        return valorResultado;
    }
}

Ao chamar este método de extensão no método Main - quando usamos uma instância string chamada textoNumero e exibimos a lista de métodos disponíveis, podemos encontrar nosso método ConverterParaInt() usando as setas ↑ ↓. Ele tem um ícone diferante dos métodos normais.

string textoNumero = "42";
var resultado = textoNumero.ConverterParaInt();
Console.WriteLine(resultado); // Saída: 42

Exemplo: O tipo Array nativo não suporta funcionalidade de "fatiamento", mas podemos implementar essa funcionalidade através de métodos de extensão

static class UtilitariosArray
{
    /// <summary>
    /// Fornece um método de extensão para converter string em inteiro
    /// </summary>
    /// <param name="entradaTexto">Valor string a ser convertido</param>
    /// <returns>Valor inteiro após conversão bem-sucedida</returns>
    public static int ConverterParaInt(this string entradaTexto)
    {
        int valorResultado = 0;
        if (int.TryParse(entradaTexto, out valorResultado))
        {
            return valorResultado;
        }
        return valorResultado;
    }

    /// <summary>
    /// Fornece método de extensão para arrays genéricos - funcionalidade de fatiamento
    /// </summary>
    /// <typeparam name="TElemento"></typeparam>
    /// <param name="origemArray">Array a ser fatiado</param>
    /// <param name="posicaoInicio">Início do fatiamento na posição especificada</param>
    /// <param name="quantidadeElementos">Quantidade de elementos a extrair</param>
    /// <returns>Novo array resultante do fatiamento</returns>
    public static TElemento[] Fatiar<telemento>(this TElemento[] origemArray, int posicaoInicio, int quantidadeElementos)
    {
        TElemento[] resultadoArray = null;
        
        if (posicaoInicio < 0 || quantidadeElementos < 0 || 
            origemArray == null || origemArray.Length - posicaoInicio < quantidadeElementos)
        {
            return resultadoArray;
        }
        else
        {
            resultadoArray = new TElemento[quantidadeElementos];
            Array.Copy(origemArray, posicaoInicio, resultadoArray, 0, quantidadeElementos);
            return resultadoArray;
        }
    }
}
</telemento>

Chamando o método de extensão de fatiamento no método Main

string[] arrayOriginal = new string[] { "10", "25", "36", "49", "58", "63" };
var arrayFatiado = arrayOriginal.Fatiar(2, 3);

if (arrayFatiado != null)
{
    foreach (var elemento in arrayFatiado)
    {
        Console.WriteLine(elemento.ConverterParaInt());
    }
}
// Saída: 36 49 58

Métodos de extensão têm ampla aplicação no desenvolvimento diário, mas é importante evitar declarar métodos de extensão para o tipo object. Além disso, os métodos de extensão desempenham um papel crucial no LINQ, como o método Where() que usamos frequentemente em coleções.

Tags: CSharp metodos-extensao programacao-orientada-objetos linq generics

Publicado em 9-28 12:16