quinta-feira, 18 de novembro de 2010

Web Designers vs Web Developers


Web Designers vs Web Developers is brought to you by Wix.com
Use creative design to make a Free Website
You are most welcome to share this infographic with your audience.

quinta-feira, 7 de outubro de 2010

segunda-feira, 4 de outubro de 2010

Introdução a expressões Lambda em C#


Para entender o que são expressões lambda, devemos voltar um pouco no tempo. Vamos voltar ao tempo do .NET 1.0 (C# 1.0) e iniciar com o conceito de delegates. O conceito de delegates não é tão novo como o advento do .NET. Ele veio antes, em C por exemplo, era chamado de "ponteiro para função"  (expressão que diz mais sobre o que um delegate realmente faz). Um delegate, como o "ponteiro para função", guarda uma  referência a uma função (ou método - o que você preferir) e permite que chamemos essa função quando precisarmos.
Em .NET, os "ponteiros para função" foram chamados de delegates e adicionou-se segurança de tipo a ele,  o que significa que, em um delegate, devemos especificar exatamente o tipo do resultado que a função apontada retorna e os argumentos (e os tipos de seus argumentos) que essa função espera receber.  Podemos, então, usar o delegate para apontar para um método que tenha a assinatura especificada (se tentarmos apontar para uma função  com assinatura diferente da especificada, receberemos erro no momento da compilação - Ótimo!)

Podemos,  então, passar esse delegate pra frente como se fosse uma variável:

internal sealed class Program
{
     //Definição do Delegate
    public delegate void MyCoolDelegate(string arg);

     static void Main(string[] args)
    {
                  //criando um delegate e apontando-o para o método "PrintToConsole"
                  MyCoolDelegate myCool = new MyCoolDelegate(PrintToConsole);

                  //chamando o delegate
                  myCool(“Test”);
    }

    public static void PrintToConsole(string value)
    {
                  Console.WriteLine(value);
     }
}

Um delegate é apenas uma referência a um método que você pode usar como uma variável. Podemos passa-lo a um método e chamá-lo onde for necessário. Esse é um conceito poderoso pois com eles, podemos tratar funções e métodos como dados, como fazemos com as variáveis. Funções se tornaram "cidadãos de primeira classe". (outro uso interessante dos delegates é para fazer chamadas assíncronas a métodos, facilitando o modo de fazer multithreading... vou passar por isso outro dia).
                Vamos avançar um pouco e parar no tempo quando o .NET 2.0 e o C# 2.0 foram lançados. Para o C# 2.0, o time de desenvolvimento dessa ferramenta adicionou uma coisa muito legal e útil: Métodos Anônimos (ou anonymous delegates). A diferença entre os métodos anônimos e os delegates tradicionais (como o eram no .NET 1.0) é que não precisamos mais definir um método em algum outro lugar do código e apontá-lo como o delegate para que ele funcione. Com os métodos anônimos, definimos o método a chamar no mesmo instante em que criamos o delegate e o compilador de C# tomará os cuidados necessários. O compilador C# criará o método para nós e o converterá em algo que pareça exatamente como no .NET 1.0.
Vamos comparar o funcionamento de um delegate tradicional com um método anônimo:

     // o modo tradicional
       internal sealed class Program
       {
           static void Main(string[] args)
           {
                  //criando uma lista com alguns dados
                  List<string> list = new List<string>();
                  list.Add(“value1");
                  list.Add(“value2");

                  //procura na lista. Precisamos especificar um método
                  //aqui que conterá a lógica para encontrar os dados que precisamos
                  string result = list.Find(new Predicate<string>(FindInList));
        }

         //Método utilizado para procurar o dado na lista
             static bool FindInList(string value)
             {
                  return (value == “value2");
             }
    }

     //agora, utilizando método anônimo
     internal sealed class Program
     {
          static void Main(string[] args)
         {
                  //criando uma lista com alguns dados
                  List<string> list = new List<string>();
                  list.Add(“value1");
                  list.Add(“value2");

                  //procurando na lista utilizando um método anônimo
                  string result = list.Find(delegate(string value){ return (value == “value2"); });
          }
    }


Podemos ver claramente a diferença aqui. Com os métodos anônimos, não precisamos criar outro método e um delegate que aponta para esse método. Dizemos apenas que queremos um delegate aqui e especificamos o corpo do método a ser chamado. É muito mais conveniente utilizar um método anônimo ao invés do modo com delegate tradicional. O definição do código a utilizar fica junto a sua utilização. Outra característica introduzida com os métodos anônimos é a possibilidade de usar variáveis definidas fora do método anônimo:

    static void Main(string[] args)
    {
                  //criando uma lista com alguns dados
                  List<string> list = new List<string>();
                  list.Add(“value1");
                  list.Add(“value2");

                  string toFind = “value2";
                  
                   //utilizando variável externa ao método anônimo (toFind)
                  string result = list.Find(delegate(string value) { return (value == toFind); });
    }

                  Neste exemplo vemos o uso da variável "toFinde" dentro corpo do método do delegate embora tenhamos o definido fora dele. Neste caso, o compilador C# não somente cria o método para nós mas toda uma classe (que contém o método) onde o valor que usaremos no corpo do delegate é passado como um membro dessa classe.
Nos dias de hoje, no C#3.0 (e no .NET 3.5) temos as expressões Lambda que são o próximo passo na "evolução do delegate". Agora, o compilador faz sumir o "delegate(...) {...}" (economizando um monte de digitação). Uma expressão lambda sempre consiste de duas partes (esquerda e direita) separadas por um "=>". A parte à esquerda do "=>" contém uma lista de argumentos (não necessariamente tipados pois os tipos podem ser automáticamente indicados pelo compilador). O lado direito contém o corpo do método. Uma expressão lambda, ainda, sempre espera um valor de retorno (por isso não podemos omitir a palavra-chave "return"):

    static void Main(string[] args)
    {
                  // criando uma lista com alguns dados
                  List<string> list = new List<string>();
                  list.Add(“value1");
                  list.Add(“value2");

                  string toFind = “value2";

                  //utilizando uma expressão lambda
                  string result = list.Find(value => toFind == value);
    }


Para resumir: expressões lambda são delegates (ou "ponteiros para função" com segurança de tipo). Elas só têm essa aparência devido a alguns pressupostos adotados, como o fato das expressões lambda serem funções e deverem sempre retornar algo e que os tipos podem ser automáticamente informados pelo compilador. Um efeito colateral bom das expressões lambda é que elas, no mínimo, nos economizam muita digitação e muito tempo de desenvolvimento (além de organizar muito mais nossos códigos).
(baseado no artigo:  http://msdn.microsoft.com/en-us/library/bb397687(VS.90).aspx)