Extension Methods no C#

5 comentários

Apesar de ser um assunto de certa forma “esgotado”, que muitos estão cansados de saber, resolvi escrever este post, pois acho uma opção interessante para os desenvolvedores da plataforma .net.

Os métodos de extensão surgiram junto com o .Net Framework 3.5, e permitem adicionarmos novas funcionalidades a tipos existentes, sem a necessidade de alterar o tipo original e recompilá-lo. Devem sempre ser métodos estáticos, mas a chamada para eles é muito parecida com a chamada para métodos de instância. O primeiro parâmetro especifica em qual o tipo que método opera e deve sempre ser seguido da palavra chave this.

A classe que conterá o método de extensão, assim como o próprio método, também deve ser estática e a Namespace deve ser declarada nos locais onde o método de extensão deverá ficar disponível, através de using.

OBS: Todos os códigos contidos neste artigo estão em Linguagem C#

Vejamos um exemplo de criação método de extensão:

// C#
public static class MetodosDeExtensao
{
    /// <summary>
    /// Verifica se um objeto é nulo
    /// </summary>
    /// <param name="obj">object, objeto a ser verificado</param>
    /// <returns>bool, true quando o objeto for nulo</returns>
    public static bool IsNull(this object obj)
    {
        if (obj == null)
            return true;
        else
            return false;
    }
}

No exemplo acima, fizemos um método de extensão que verifica se um objeto é nulo ou não. É possível ver a palavra chave this antes a declaração do primeiro parâmetro do método, que é o identificador do tipo onde o método de extensão será aplicado.

O método em sí, terá a mesma estrutura de qualquer outro método estático, ou seja, não muda nada na forma de desenvolvimento e poderá ser usado normalmente como um método estático. Veja:

// C#
// utilizando a maneira convencional
string strNome = "Fernando Ottoboni";
if (MetodosDeExtensao.IsNull(strNome))
    Console.WriteLine("Nome não informado.");

Mas já que estamos falando de métodos de extensão, vamos então ver a forma correta de utilização do mesmo.

A partir do momento que o método de extensão foi criado, em todos os locais onde a namespace estiver acessível (lembre-se do using), o tipo declarado no método passará a conter uma nova extensão. Veja:

A seguir é possível ver um exemplo da sintaxe completa de utilização do nosso método de extensão.

// C#
// utilizando o método de extensão
string strNome = "Fernando Ottoboni";
if (strNome.IsNull())
    Console.WriteLine("Nome não informado.");

Em algumas situações, precisamos fazer métodos que devem ter dois ou mais parâmetros de entrada. Isso também é possível em métodos de extensão, mas devemos lembrar que sempre precisamos colocar o this no primeiro parâmetro (sempre no primeiro e somente nele). Os parâmetros restantes serão parâmetros comuns. Vejamos um exemplo:

// C#
/// <summary>
/// Completa a string com a quantidade e o caracter informado
/// </summary>
/// <param name="str">String, string a ser completada</param>
/// <param name="caracter">String, caracter a ser usado ao completar</param>
/// <param name="qt">Int, quantidade de caracteres</param>
/// <returns>String, string completada com os caracters</returns>
public static string CompletarString(this string str, string caracter, int qt)
{
    if (string.IsNullOrEmpty(str))
        str = "";

    if (caracter.Length > 1)
        caracter = caracter.Substring(0, 1);

    StringBuilder stb = new StringBuilder();

    if (string.IsNullOrEmpty(caracter.ToString()))
        caracter = " ";

    if (qt - str.Length > 0)
    {
        qt = qt - str.Length;
        stb.Append(str);
        stb.Append(new String(Convert.ToChar(caracter), qt));
    }
    else
    {
        stb.Append(str.Substring(0, qt));
    }

    return stb.ToString();
}

Existem várias outras situações e cenários onde podemos usar métodos de extensão. Vejamos então alguns lugares interessantes:

  • IsNullOrEmpty

Adquiri tão rapidamente o costume de usar métodos de extensão, que tive que fazer tornar o IsNullOrEmpty (String.IsNullOrEmpty) um deles apenas por conveniência.

// C#
/// <summary>Verficar se uma string é nula ou vazia</summary>
public static bool IsNullOrEmpty(this string str)
{
    return string.IsNullOrEmpty(str);
}
  • IsNullOrWhiteSpace

Assim como os IsNullOrEmpty, o mesmo pode ser feito com o IsNullOrWhiteSpace (String.IsNullOrWhiteSpace).

// C#
/// <summary>
/// Verficar se uma string é nula ou espaço em branco
/// </summary>
public static bool IsNullOrWhiteSpace(this string str)
{
    return string.IsNullOrWhiteSpace(str);
}
  • IsDateTime

Verificar se um string é um DateTime válido.

// C#
/// <summary>
/// Verificar se o conteúdo da string equivale a um DateTime
/// </summary>
public static bool IsDateTime(this string str)
{
    string strData = str;

    if (string.IsNullOrEmpty(strData))
        return false;

    try
    {
        DateTime datData = Convert.ToDateTime(strData);
        return true;
    }
    catch
    {
        return false;
    }
}
  • IsDecimal

Verificar se um string é um Decimal válido.

// C#
/// <summary>
/// Verificar se o conteúdo da string equivale a um decimal.
/// </summary>
public static bool IsDecimal(this string str)
{
    if (String.IsNullOrEmpty(str))
        return false;

    try
    {
        Convert.ToDecimal(str);
        return true;
    }
    catch
    {
        return false;
    }
}
  • ReverseString

Retorna a string reversa.

// C#
/// <summary>
/// Retorna a string de forma reversa
/// </summary>
/// <param name="str">String a ser revertida</param>
/// <returns>String revertida</returns>
public static string ReverseString(this string str)
{
    char[] arr = str.ToCharArray();
    Array.Reverse(arr);
    return new string(arr);
}
  • Left

Extrai um Substring do lado esquerdo da string conforme a quantidade de caracteres desejada.

// C#
/// <summary>
/// Extrai um Substring do lado esquerdo da string
/// conforme a quantidade de caracteres desejada
/// </summary>
/// <param name="str">String para extrair o substring</param>
/// <param name="length">Quantidade de caracteres a extrair</param>
/// <returns>String</returns>
public static string Left(this string str, int length)
{
    if (str.IsNullOrEmpty())
        return str;

    if (str.Length <= length)
        return str;

    return str.Substring(0, length);
}
  • Right

Extrai um Substring do lado direito da string conforme a quantidade de caracteres desejada.

OBS: Usa o método ReverseString.

// C#
/// <summary>
/// Extrai um Substring do lado direito da string conforme a quantidade de caracteres desejada
/// </summary>
/// <param name="str">String para extrair o substring</param>
/// <param name="length">Quantidade de caracteres a extrair</param>
/// <returns>String</returns>
public static string Right(this string str, int length)
{
    if (str.IsNullOrEmpty())
        return str;

    if (str.Length <= length)
        return str;

    return str.ReverseString().Substring(0, length).ReverseString();
}

Existem muitas outras possibilidades, e no código fonte que pode ser baixado logo abaixo coloquei alguns outros exemplos.

LINQ e os Métodos de Extensão

Há algum tempo, fiz um artigo que mostrei como utilizar e como funcionam os métodos de extensão disponíveis para utilização com LINQ. Se quiser conferir, basta clicar aqui.

Códigos fontes

Os códigos-fontes deste artigo podem ser baixados aqui.

Referências

Anúncios

Novo artigo no iMasters

Deixe um comentário

Mais um artigo publicado no iMasters:

Recebendo retornos de threads em C#

Existem situações em que é necessário retornar informações quando a execução da thread estiver concluída para que elas sejam usadas na continuação do processamento da thread principal da aplicação. O intuito deste artigo é mostrar uma maneira de receber e tratar retornos de threads.

Neste link: imasters.com.br/artigo/19615/c-sharp/recebendo-retornos-de-threads-em-c

Vale a pena conferir!

Obrigado.