Um recurso disponibilizado a partir do C# 3.0 pode estender funcionalidades de uma classe especifica do framework.

O mais comum quando precisamos criar métodos úteis é criando classes static “helper”, “util” ou algo parecido, digamos que você passou um bom tempo criando classes e métodos que facilita o seu dia-a-dia em um projeto, digamos também que você criou tudo isso em um projeto separado e compilou em um DLL (para poder utilizar nos próximos projetos). Acontece que você fica um tempo sem precisar de um método e quando vai utilizá-lo você esquece dos namespaces, o nome dos métodos, vamos multiplicar isso para uma equipe com vários desenvolvedores que também vai esquecer os namespaces (pois já temos que lembrar de vários).

Bom, podemos criar Extension Methods e colocar esses métodos uteis junto com os métodos já existentes na classe.

Vamos criar um projeto do tipo console application eu estou utilizando o visual Studio 2010 mas, você poderá utilizar o visual Studio 2008 lembrando que o framework .net deve ser igual ou superior ao 3.0.

O que vamos fazer primeiro é criar uma classe static para os métodos uteis comuns, ou seja, da forma que estamos acostumados a criar e utilizar.

public static class comumUtil

            {
            
                public static String FormataCapitalize(string Str)
            
                {
            
                    Str = Str.ToLower();
            
                    System.Globalization.CultureInfo cultureinfo = System.Threading.Thread.CurrentThread.CurrentCulture;
            
                    return cultureinfo.TextInfo.ToTitleCase(Str);
            
                }
            
            }

Como podemos ver um método que recebe uma string e transforma a primeira letra de todas as palavras e maiúscula e o restante e minúscula e retorna uma string com o resultado dessa transformação, não vamos entrar em detalhes o seu funcionamento.

A utilização do método FormataCapitalize obriga conhecer o nome completo da classe incluindo manespaces, vamos ver logo abaixo.

Console.WriteLine(comumUtil.FormataCapitalize("tESTE cOM metodo comum"));

Observem que, teremos que escrever o nome da classe “ponto” o método e passar como parâmetro uma string.

Seria muito mais intuitivo e pratico se quando estivermos em um objeto do tipo string colocássemos um “ponto” e o nosso método estivesse lá, bem no meio dos métodos já compilados na classe em questão.

E é isso que vamos fazer agora, não é complicado nem mesmo requer muitas alterações no que já temos, pode levar alguns minutos para você familiarizar.

Bom o que precisamos e é uma regra, é colocarmos o um “this” na frente do tipo do primeiro parâmetro e é esse tipo que indica qual classe será estendida, então vamos conferir como fica o nosso método estendido.

public static class ExtensionUtil

            {
            
                public static String FormataCapitalize(this string Str)
            
                {
            
                    Str = Str.ToLower();
            
                    System.Globalization.CultureInfo cultureinfo = System.Threading.Thread.CurrentThread.CurrentCulture;
            
                    return cultureinfo.TextInfo.ToTitleCase(Str);
            
                }
            
            }

Agora podemos utilizar esse método de forma pratica e intuitiva.

Console.WriteLine("tESTE cOM metodo extension".FormataCapitalize());

Isso não é realmente pratico e intuitivo?

Digamos que, temos que além do parâmetro “this” também precisássemos passar outros parâmetros. Isso também é simples, pois como eu disse a única diferença é o “this” o restante é igual a métodos estáticos comum.

Vamos ver outro exemplo de extension methods.


            public static String FormataMoeda(this Double valor, String formato, IFormatProvider FormatProvider)

            {
            
             
            
                if (string.IsNullOrEmpty(formato))
            
                    formato = "{0:c}";
            
                try
            
                {
            
                    if (FormatProvider != null)
            
                        return String.Format(FormatProvider, formato, valor);
            
                    else
            
                        return String.Format(formato, valor);
            
                }
            
                catch
            
                {
            
                    return valor.ToString();
            
                }
            
            }
            

Esse método estende um Double criando a possibilidade de você formatar o valor e converter para string e ainda informar qual o FormatProvider, utilizando o CultureInfo ou outro qualquer.

Exemplos de utilizações.


            Console.WriteLine(valor.FormataMoeda("{0:c}", new CultureInfo("en-US")));

            Console.WriteLine(valor.FormataMoeda("R$ {0:#,##0.00}", new CultureInfo("pt-BR")));
            

Nas chamadas o primeiro parâmetro é ocultado (pois ele é o valor do próprio objeto) e temos que informas os demais parâmetros.

E por ultimo vamos ver como estender os genéricos (using System.Collections.Generic;), bem vamos imaginar um cenário onde temos que ter um valor chave da nossa lista em uma única string separada por algum caracter. E também podemos ter um lista de string e também queremos essa lista em uma string separada por um caracter, bom queremos lista de qualquer tipo e valores chaves separados por algum caracter. Ficou difícil não é?

A resposta é não, vamos utilizar genéricos e reflexão, o genérico fica por conta do List<> e a reflexão vai ficar por conta de pegar o valor de um campo em um determinado objeto complexo.

Então vamos ver o nosso Extension Method.


            public static String TodosOsValoresString(this List list, string Campo, string Separador)

{

    StringBuilder Retorno = new StringBuilder("");

    if (list.Count > 0)

    {

        for (int i = 0; i <= list.Count - 1; i++)

        {

            Retorno.AppendFormat(

                (list.Count - 1 != i ?

                    "{0}{1}" :

                    "{0}"

                ),

                (string.IsNullOrEmpty(Campo) == true ?

                    list[i].ToString() :

                    list[i].GetType().GetProperty(Campo).GetValue(list[i], null).ToString()

                ),

                Separador

            );

        }

    }

    return Retorno.ToString();

}

Ai nosso Extension Method genérico. Abaixo exemplos de utilização.

List<string> Nomes = new List<string>();

Nomes.Add("Caio");

Nomes.Add("Humberto");

Nomes.Add("Francisco");

Console.WriteLine(Nomes.TodosOsValoresString(null, ","));

 

List<int> Val = new List<int>();

Val.Add(1);

Val.Add(2);

Val.Add(3);

Console.WriteLine(Val.TodosOsValoresString(null, ","));
            

Bom galera, espero que tenham gostado dos exemplos e forma de aplicação desse recurso, lembrando que você criar extension methods para todas as classes já compilada onde você não possa adicionar métodos.

No exemplo vocês vão encontrar outras formas de aplicações dos exemplos e vocês vão poder tirar um melhor proveito nos estudos.

Chegamos ao fim deste artigo, espero novamente ter conseguido passar a idéia desse recurso. Até a próxima, ahh não se esqueçam de fazer o download do exemplo.