Thứ Hai, 11 tháng 7, 2016


lambda

Series C# hay ho: Lambda Expression

1. Ôn lại khái niệm Delegate
Các bạn vui lòng đọc lại bài trước để nhớ lại các khái niệm về delegate ở đây: Series C# hay ho: Callback trong C# – Delegate, Action, Predicate, Func
Như đã nói ở bài trước, delegate là kiểu dữ liệu để trỏ tới 1 function, do đó khi gán giá trị cho delegate, ta phải gán 1 function vào, như ví dụ dưới đây:
1
2
3
4
5
6
7
8
9
public delegate void TangQuaDelegate(string qua);
public void tangQua(string qua) {
   Console.Write("Da tang " + qua);
}
//Khi sử dụng:
TangQuaDelegate dlg = tangQua;
//Truyền function vào, không phải thực thi function nên ko có dấu ()

2. Anonymous function
Như vậy, mỗi lần muốn truyền 1 function vào delegate, ta phải define function đó, khá phiền phức nhỉ? Trong javascript có anonymous method, viết thẳng function mà ko cần define như sau:
1
2
3
4
5
6
7
8
9
10
//Dùng anonmyous function, tangQuaDlg giờ đã là 1 delegate
var tangQuaDlg = function(qua) { alert("qua"); };
function oNha(vo, tangQua){
   var qua = "Quà đã nhận";
   tangQua(qua);
}
//Sử dụng trong code
oNha(vo, tangQuaDlg);
May mắn thay, trong C#, ta cũng có thể viết anonymous function theo cách sau (Từ .NET 2.0):
1
2
3
4
public delegate void TangQuaDelegate(string qua);
TangQuaDelegate dlg =
          delegate(string qua) { Console.WriteLine("Tang quà" + qua); };
Ta thấy viết delegate cách này khá là rườm rà phải không? Microsoft cũng thấy vậy, và họ đã bổ sung lambda expression và .NET 3.0. Muốn biết lambda expression là gì, mới xem phần dưới.
3. Lambda expression
Mình muốn nhắc lại 1 chuyện lần thứ n là: “Các lão developer bên Microsoft rất lười, do đó họ thêm vào C#.NET nhiều thứ, làm developer C#.NET lười theo”. Ta có thể hiểu lambda expression là 1 cách viết anonymous function ngắn gọn hơn:
1
2
3
4
5
6
7
8
9
//Cách cũ
TangQuaDelegate dlg = delegate(string qua) { Console.WriteLine("Tặng quà" + qua); };
//Dùng lambda expression
TangQuaDelegate lamdaDlg = (qua) => { Console.WriteLine("Tặng quà: " + qua); }
//Câu lệnh đầy đủ của lambda expression.
//Dấu "=>" gọi là go-to
(parameters) => { statement }
1
Dưới đây là một số qui tắc viết lambda expression:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//1. Có thể bỏ qua kiểu dữ liệu của parameter truyền vào
(string qua) => {Console.WriteLine("Tặng quà: " + qua);}
(qua) => {Console.WriteLine("Tặng quà: " + qua);}
//2. Nếu không có parameter, bỏ dấu () trống
() => {Console.WriteLine("Hello");}
//3. Nếu chỉ có 1 parameter, có thể bỏ luôn dấu ()
(x) => {Console.WriteLine("Hello " + x);}
x => {Console.WriteLine("Hello " + x);}
//4. Nếu có nhiều parameter, ngăn cách bằng dấu phẩy
(x, y) => {Console.WriteLine("Hello " + x + y);}
//5. Nếu anonymous function chỉ có 1 câu lệnh, có thể bỏ dấu {}
x => { Console.WriteLine("Hello " + x); }
x => Console.WriteLine("Hello " + x)
//6. Nếu chỉ return 1 giá trị, có thể bỏ chữ return.
//4 lambda expression sau tương đương nhau
(x) => { return x > 4; }
x => { return x > 4; }
x => return x > 4
x => x > 4
Tới đây, có bạn sẽ ồ lên kinh ngạc: “À, ra vậy”. Đây là cách ta áp dụng các bước trên để rút gọn 1 lambda expression.
Capture
Cũng có bạn sẽ thắc mắc: Ớ, tưởng lambda expression là gì ghê gớm chứ, hóa ra đơn giản thế thôi à. Vâng, vì nó đơn giản thế nên nhiều bạn sử dụng nó mà không biết tên gọi cũng như chính xác nó là gì.
4. Lambda Expression và LINQ
Đã có bao giờ bạn xem thử param truyền vào cho 1 hàm của LINQ như Where, First là gì chưa?. Vâng, nó chính là 1 delegate cho một function có kiểu trả về là bool (Xem thêm về Func ở bài trước).
Untitled
Do đó, ta sử dụng lambda expression để truyền 1 anonymous function vào hàm Where hoặc First. Ví dụ, khi dùng hàm Where của LINQ để tìm những phần tử trong 1 mảng:
1
2
3
4
5
6
7
8
9
10
11
var studentList = new List<Student>();
//Thứ đẹp đẽ ngắn gọn này là lambda expression
var students = studentList.Where(stu => stu.Age > 20);
//Nếu không có nó, ta phải viết cái thứ vừa dài dòng vừa gớm ghiếc như sau
var student = studentList.Where(new delegate(Student stu) { return stu.Age > 20; });
//Hoặc tệ hơn
public bool FindStudentWithAge(Student stu) { return stu.Age > 20; }
var student = studentList.Where(FindStudentWithAge);
Chúc mừng các bạn đã biết được thêm 1 điều hay ho mà ít người biết trong C#.NET. Lambda expression cũng như anonymous function là những vấn đề có tính chuyên sâu trong .NET, có thể bạn sẽ bị hỏi nếu muốn apply vào vị trí senior developer đấy nhé.
Bài viết xin kết thúc ở đây. Hai bài viết tiếp theo sẽ là về Generic và IEnumrable, mong các bạn đón xem.
pr-2

About these ads

Không có nhận xét nào:

Đăng nhận xét