Jan 7, 2011

4:09 AM - No comments

Lambda Expressions

Nếu anonymous method (tạm dịch: phương thức nặc danh) trong C# 2.0 cho phép bạn bạn khai báo phương thức của bạn theo kiểu inline (có thể tạm hiểu là ngay lập tức hay trực tiếp) thay vì phải khai báo một delegate function như trước đây thì đến lược C# 3.0, lambda expressions ra đời lại cung cấp tiếp một phương pháp khác ngắn gọn và xúc tích hơn, nhưng vẫn đạt được cùng một mục đích.

Trước tiên, xin nhắc lại về anonymous method:

Giả sử bạn muốn tạo một button để updates một ListBox trên form mỗi khi click lên nó. Trong C# 1.0, bạn sẽ phải làm như sau:

public MyForm()
{
listBox = new ListBox(...);
textBox = new TextBox(...);
addButton = new Button(...);
addButton.Click += new EventHandler(AddClick);
}
void AddClick(object sender, EventArgs e)
{
listBox.Items.Add(textBox.Text);
}

Đến C# 2.0, công việc trông có vẻ đơn giản hơn một chút:

public MyForm()
{
listBox = new ListBox(...);
textBox = new TextBox(...);
addButton = new Button(...);
addButton.Click += delegate
{
listBox.Items.Add(textBox.Text);
};

Như bạn thấy, với việc sử dụng anonymous methods trong C# 2.0, bạn không cần phải khai báo tường minh method của mình và gắn nó vào event như trước. Tuy nhiên, hãy xem lambda expressions trong C# 3.0 làm được những gì:

Parameters to Lambda Expressions

Cú pháp của lambda expression thật sự đơn giản. Bắt đầu với một parameter (hoặc parameter list), theo sau đó là toán tử =>, tiếp theo là 1 expression hoặc block of statement.

Parameters của lambda expressions có thể xác định tường minh (explicitly) và không tường minh (implicitly). Với kiểu tường minh, kiểu của param của mỗi expression sẽ được xác định rõ. Trong kiểu không tường minh, kiểu của param sẽ được suy ra từ ngữ cảnh mà lambda expression diễn ra.

(int x) => x + 1 // explicitly typed parameter
(y,z) => return y * z; // implicitly typed parameter

Lambda Expressions Demonstration

Đoạn code dưới đây mô tả 2 cách thức để in ra các chuỗi có length là một số chẵn. Cách đầu tiên được implement trong hàm AnonMethod, là một anonymous methods.
Cách còn lại, được implement trong LambdaExample, sử dụng lambda expression:

// Program.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Query;
using System.Xml.XLinq;
using System.Data.DLinq;
namespace LambdaExample
{
public delegate bool KeyValueFilter(K key, V value);
static class Program
{
static void Main(string[] args)
{
List list = new List();
list.Add("AA");
list.Add("ABC");
list.Add("DEFG");
list.Add("XYZ");
Console.WriteLine("Through Anonymous method");
AnonMethod(list);
Console.WriteLine("Through Lambda expression");
LambdaExample(list);
Dictionary varClothes= new Dictionary();
varClothes.Add("Jeans", 20);
varClothes.Add("Shirts", 15);
varClothes.Add("Pajamas", 9);
varClothes.Add("Shoes", 9);
var ClothesListShortage = varClothes.FilterBy((string name,
int count) => name == "Shoes" && count <> if(ClothesListShortage.Count > 0)
Console.WriteLine("We are short of shoes");
Console.ReadLine();
}
static void AnonMethod(List list)
{

List evenNumbers =
list.FindAll(delegate(string i)
{ return (i.Length % 2) == 0; });
foreach (string evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
static void LambdaExample(List list)
{
var evenNumbers = list.FindAll(i =>
(i.Length % 2) == 0); // example of single parameter
foreach(string i in evenNumbers)
{
Console.WriteLine(i);
}
}
}
public static class Extensions
{
public static Dictionary FilterBy
(this Dictionary items, KeyValueFilter filter)
{
var result = new Dictionary();
foreach(KeyValuePair element in items)
{
if (filter(element.Key, element.Value))
result.Add(element.Key, element.Value);
}
return result;
}
}
}

0 comments:

Post a Comment