Delegate-Tasks

Series C# hay ho: Callback trong C# – Delegate, Action, Predicate, Func

1. Nhắc lại về khái niệm callback

Nếu chưa có khái niệm rõ ràng về callback, các bạn nên đọc bài viết về Callback trong javascript mà mình đã viết.

Trong javascript, để callback, ta chỉ cần truyền 1 function vào như 1 parameter như sau:


function tangQua(qua) {
   return console.log("Đã tặng " + qua);  
}

function oNha(vo, tangQua){
   var qua = "Quà đã nhận";
   tangQua(qua);
}

2. Delegate trong C#

Trong javascript, function cũng xem như là 1 object, nên ta có thể truyền function vào như 1 param. Khi ta thử viết lại chương trình trên trong C#, ta phải khai báo kiểu dữ liệu cho parameter truyền vào, vậy kiểu dữ liệu của function “tangqua” là gì?


public void tangQua(string qua) {
   Console.Write("Da tang " + qua);
}

 //Kiểu dữ liệu cho params "vo" là Person, kiểu dữ liệu cho tangQua là gì???
public void oNha(Person vo, tangQua){
   var qua = "Quà đã nhận";
   tangQua(qua);
}

Ở đây, để truyền function tangQua vào, ta phải sử dụng kiểu dữ liệu Delegate (Con trỏ hàm). Ta khai báo delegate theo cú pháp sau:

 public delegate void TangQuaDelegate(string qua);
 //delage + kiểu trả về (void) + tên delegate + (tham số truyền vào)

 public void tangQua(string qua) {
    Console.Write("Da tang " + qua);
 }

 public void oNha(Person vo, TangQuaDelegate tangQua)
 {
    var qua = "Quà đã nhận";
    tangQua(qua);
 }

Trong C#, delegate thường được sử dụng phối hợp với event. Các bạn làm Winform chắc ko lạ lùng với những đoạn code gọi event thế này:

 this.button1.Click += new System.EventHandler(this.button1_Click);

//Thật sự thì event handler chỉ là 1 delegate
 public delegate void EventHandler(object sender, EventArgs e);

//Function chúng ta truyền vào chính là function với 2 param sender, a, kiểu trả về la void
 private void button1_Click(object sender, EventArgs e) { }

Bài viết này chỉ tập trung về delegate nên các bạn có thể tìm hiểu thêm về delegate và event ở trang khác nhé.

http://tapchilaptrinh.vn/2012/07/16/delegates-va-events-trong-c/

3. Action, Predicate, Func trong C#

Ở phần này, mình xin giới thiệu về Action, Predicate, Func (Viết tắt là APF là cho nhanh) trong C#. Như các bạn đã đọc trong series C# hay ho, các lão developer trong Microsoft rất lười. Do đó họ luôn thêm thắt nhiều thứ trong C# để các developer chúng ta cũng lười như họ. APF thật ra là 1 cách lười hơn để chúng ta khai báo delegate.

Dưới đây là khái niệm cũng như cách dùng APF :

  • Action: Action<T in1, T in2, …>. Action tương đương 1 delegate với kiểu trả về là void, với in1, in2 là các params nhận vào.
  • Predicate: Predicate<T in1, T in2, …>. Predicate tương đương 1 delegate với kiểu trả về là bool, với in1, in2 là các params nhận vào
  • Func: Func<T in1, T in2, … , T result>. Function tương đương 1 delegate với kiểu trả về do ta khai báo (result), in1, in2 là các params nhận vào. Func bắt buộc phải trả ra giá trị, không thể trả void.

Để dễ hiểu, các bạn hãy tham khảo bảng sau. Đây là bảng so sánh các khai báo bằng delegate, cùng với cách khai báo tương ứng bằng Action, Predicate, Func:

Delegate Action Predicate Func
delegate void VoidDelegate(int input1, bool input2) Action<int, bool>
delegate bool BoolDelegate(int input1, bool input2) Predicate<int, bool> Func<int, bool, bool>
delegate int intDelegate(bool input2) Func<bool, int>
delegate void HelloWorldDelegate() Action
delegate bool HelloWorldBoolDelegate() Predicate  Func<bool>

Đoạn code ban đầu có thể được viết lại như sau, ngắn gọn hơn

public void tangQua(string qua) {
   Console.Write("Da tang " + qua);
}

public void oNha(Person vo, Action<string> tangQua)
{
   var qua = "Quà đã nhận";
   tangQua(qua);
}

Có thể bạn sẽ thắc mắc: Ủa, mình có thấy người khác dùng Action, Predicate, … mấy đâu, biết làm gì?

pr-2

Bạn sẽ ngạc nhiên khi biết AFP, kết hợp với lambda expression và vài thứ khác nữa …., đã tạo nên sự “bá đạo” của LINQ, thứ mà Java thèm đỏ mắt mà không có, phải thêm vào ở Java SDK 8. Nhớ đón đọc bài sau “Series C# hay ho: Lambda Expression” để biết thêm chi tiết nhé.

Advertisements

6 thoughts on “Series C# hay ho: Callback trong C# – Delegate, Action, Predicate, Func”

  1. Cảm ơn bạn vì bài chia sẽ rất hay, từ ngữ viết cuốn hút dể hiểu, hi vọng bạn sẽ có nhiều bài viết hay như thế này.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s