C# 3.0 lambda expressions

A melhor maneira que eu tenho pra descrever lambda expressions é – C# Anonymous Methods mais facilitado.

Mas o que é anonymous method no c# 2.0?

Como você deve saber no c#1.x/2.x era possível escrever códigos da seguinte forma:

class AlgumaClasse

{

delegate void AlgumDelegate();

public void InvokeMethod()

{

AlgumDelegate del = new AlgumDelegate(AlgumMetodo);

del();

}

void AlgumMetodo()

{

Console.WriteLine(“Olá mundo”);

}

}

Depois veio anonymous methods que permitem a você escrever o código acima de uma maneira mais simplificada:

class AlgumaClasse

{

delegate void AlgumDelegate();

public void InvokeMethod()

{

AlgumDelegate del = delegate()

{

Console.WriteLine(“Hello”);

};

del();

}

}

O que você vê depois do “Delegate()”, é um método anônimo.Mesmo sendo melhor que a versão do c#1x. ainda assim requer algum código:

Lambda expressions dão a você uma sintaxe mais concisa e funcional,usando a sintaxe “=>”.

O código acima usando lambda expresssions poderia ser escrito da seguinte forma:

class AlgumaClasse

{

delegate void AlgumDelegate();

public void InvokeMethod()

{

AlgumDelegate del = () => Console.WriteLine(“Hello”) ;

del();

}

}

Geralmente a sintaxe é:

Parâmetros => expressão

Agora óbvio,lambda expressions não são apenas uma maneira mais simples de se escrever métodos anônimos.Eles realmente superam em funcionalidade os métodos anônimos.Porque?:

  • Lambda expressions entendem o tipo de parâmetro que você quer passar mesmo que você os omita.Anonymous methods não permitem.
  • Lambda Expressions podem usar bloco de comandos e expressões.Anonymous methods só aceitam blocos de comandos.
  • Lambda Expressions podem ser passadas como argumentos.

Vamos falar de cada um deles:

Lambda expressions entendem o tipo de parâmetro que você quer passar mesmo que você os omita.Anonymous methods não permitem.

Palavras difíceis para algo simples:

(int x) => x + 1 ; // é o mesmo que
x => x + 1 ;

Na segunda linha o tipo está sendo omitido.

Lambda Expressions podem usar bloco de comandos e expressões.Anonymous methods só aceitam blocos de comandos.

Outra vez palavras difíceis para algo simples:

(int x) => x + 1 ; // é o mesmo que
(int x) => { return x + 1; }

Na segunda linha nós temos um bloco de comando,e na primeira nós temos uma expressão.Então a primeira é igual a segunda mas é mais fácil de entender e escrever.

Lambda Expressions podem ser passadas como argumentos.

Você pode passar lambdas expressions como argumentos para métodos genéricos.Vamos considerar o seguinte exemplo.Vamos dizer que você tivesse,um extension method,como mostrado a seguir:

public static class myExtensions
{
public static void SpankIt<T,U>(
this IEnumerable<T> source,
Func<T, U> someParameter)
{
foreach (T element in source)
Console.WriteLine(“SPANK ” + someParameter(element) + “!!”);
}
}

Você poderia usar o extension method acima,assim:

static void Main(string[] args)
{
List<String> whoToSpank = new List<String>() ;
whoToSpank.Add(“Monkey”) ;
whoToSpank.Add(“Bannana”) ;

whoToSpank.SpankIt(c => “Monkey”) ;
}

E “SPANK MONKEY !!” seria escrito duas vezes.

Mas espere um pouco.O significa o “U” no extension method?Se você colocar um breakpoint no seu extension method você vai perceber que o c# 3.0 é esperto o bastante pra saber que “U” é uma string.Você nunca citou que “U” seria uma string,ele se baseia na lambda expression que você passou.

Você não pode fazer isso com métodos anônimos.

É isso!Abraço.

Anúncios

C# Anonymous types (tipos anônimos)

No meu último post,eu falei sobre a palavra–chave var,se você ainda não o leu,recomendo que o faça agora.

Assumindo que você tenha entendido o que é “var” – vamos em frente!

No c# 2.0,vamos dizer que você quisesse representar uma pessoa,você provavelmente criaria uma classe como esta:

public class Person
{
string hairColor ;
string skinColor ;
int teethCount ;
} ….

Aí entra os tipos anônimos.Agora você pode representar esta mesma classe,sem ter que criar sua estrutura primeiro.Assim:

var monster = new {cabelo=”black”, pele=”green”,dentes=64} ;

A linha de código acima irá funcionar mesmo se você não declarar a classe chamada Person.Isso permite você criar estruturas de dados sem ter que declara-las previamente.

O código acima gera uma classe por trás das cenas que você não vê,assim:

class __Anonymous1
{
private string _cabelo = “black”;
private string _pele = “green”;
private int _dentes   = 64;

public string cabelo {get { return _cabelo; } set { _cabelo = value; }}
public string pele {get { return _pele; } set { _pele = value; }}
public int dentes {get { return _dentes; } set { _dentes = value; }}
}

Por essa classe ser um tipo anonimo ela não possui nome quando é gerada pelo compilador c#,é um “System.Type”.

É isso, até a próxima.

C# 3.0 variáveis tipo var

Desmitificando o c# 3.0 keyword var

No c# 2.0 você podia declarar um integer (ou qualquer outro tipo conhecido)como

int i;

Você também podia escrever algo assim:

int i  = 1;

Ou seja:

<tipo><nomevariavel> = <inicializador>;

Ok,bom.A coisa importante pra se notar é que “i” é um inteiro.Em c# 3.0 o código abaixo é válido:

var i = 1;

Mas o que é “var”?”var” é…hum…uma palavra chave,que resulta em “i” sendo do mesmo tipo do inicializador,nesse caso um inteiro.Então var i = 1;irá resultar em uma variável chamada “i” cujo tipo é integer.

Mas qual a diferença entre “var”,object, e variant(VB6)?

Variants eram tranqueiras,que aceitavam praticamente tudo,ocupando bastante espaço na memória.Objects tem problemas de box e unboxing.E variants e objects ambos não são fortemente tipados.

Note que “i”,é um tipo fortemente tipado para integer – não é nem um objeto nem uma variant,nem carrega os problemas de nenhuma das duas.Para garantir a natureza fortemente tipada que é declarada na palavra chave var, c# 3.0 requer que você ponha no inicializador,na mesma linha da declaração.Também,o inicializador deve ser uma expressão,não um objeto ou coleção,e também não pode ser null.

Você também pode criar arrays de var:

var intArr = new[] {3,1,4,1,5} ;

Espero que tenham entendido,até a próxima!