C# delegates tương tự như con trỏ tới hàm, trong C hoặc C++. Một delegate là một biến kiểu tham chiếu chứa tham chiếu (reference type variable) đến một phương thức. Tham chiếu có thể được thay đổi trong thời gian chạy.
Delegates đặc biệt được sử dụng để thực hiện các sự kiện và các phương thức gọi lại (call-back methods). Tất cả các delegates đều được bắt nguồn từ lớp System.Delegate .
Declaring Delegates - Khai báo Delegate
Delegate declaration sẽ quyết định các method có thể được tham chiếu bởi delegate. Một delegate có thể tham chiếu tới method, mà nó có cùng chữ ký (signature) với delegate.
Ví dụ, hãy xét một delegate
public delegate int MyDelegate (string s);
Theo đó, delegate này có thể được tham chiếu bởi bất kỳ method nào mà nó có tham số truyền vào là một string và return về một biến kiểu int.
Syntax cho delegate declaration là
delegate <return type> <delegate-name> <parameter list>
Instantiating Delegates - Khởi Tạo Delegates
Khi một loại delegate được khai báo, một đối tượng delegate phải được tạo bằng từ khóa new và được liên kết với một phương thức cụ thể. Khi tạo một delegate, đối số được truyền cho biểu thức new được viết tương tự như một lệnh gọi phương thức, nhưng không có đối số cho phương thức. Ví dụ:
public delegate void printString(string s);
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
Ví dụ sau biểu thị khai báo, khởi tạo và sử dụng một delegate có thể được sử dụng để tham chiếu các phương thức lấy tham số nguyên và trả về giá trị nguyên.
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
static int num = 10;
public static int AddNum(int p) {
num += p;
return num;
}
public static int MultNum(int q) {
num *= q;
return num;
}
public static int getNum() {
return num;
}
static void Main(string[] args) {
//create delegate instances
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
//calling the methods using the delegate objects
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau -
Value of Num: 35
Value of Num: 175
Multicasting - Đa Hướng trong Delegate
Các đối tượng Delegate có thể được tạo bằng toán tử "+". Một composed delegate (delegate tổng hợp) gọi hai delegates mà nó được tạo. Chỉ các delegates cùng loại có thể được tổng hợp. Toán tử "-" có thể được sử dụng để loại bỏ một delegate thành phần khỏi một delegate tổng hợp.
Sử dụng thuộc tính this của các delegates bạn có thể tạo một danh sách các phương thức sẽ được gọi khi một delegates được gọi. Điều này được gọi là multicasting - đa hướng của một delegate. Chương trình sau đây thể hiện đa hướng của một delegate
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
static int num = 10;
public static int AddNum(int p) {
num += p;
return num;
}
public static int MultNum(int q) {
num *= q;
return num;
}
public static int getNum() {
return num;
}
static void Main(string[] args) {
//create delegate instances
NumberChanger nc;
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
nc = nc1;
nc += nc2;
//calling multicast
nc(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau
Value of Num: 75
Using Delegates
Ví dụ sau đây cho thấy việc sử dụng delegate. PrintString delegate có thể được sử dụng để tham chiếu phương thức lấy một chuỗi làm đầu vào và không trả về gì.
Chúng tôi sử dụng delegate này để gọi hai phương thức, phương thức đầu tiên in chuỗi ra bàn điều khiển và phương thức thứ hai in nó thành tập tin
using System;
using System.IO;
namespace DelegateAppl {
class PrintString {
static FileStream fs;
static StreamWriter sw;
// delegate declaration
public delegate void printString(string s);
// this method prints to the console
public static void WriteToScreen(string str) {
Console.WriteLine("The String is: {0}", str);
}
//this method prints to a file
public static void WriteToFile(string s) {
fs = new FileStream("c:\\message.txt",
FileMode.Append, FileAccess.Write);
sw = new StreamWriter(fs);
sw.WriteLine(s);
sw.Flush();
sw.Close();
fs.Close();
}
// this method takes the delegate as parameter and uses it to
// call the methods as required
public static void sendString(printString ps) {
ps("Hello World");
}
static void Main(string[] args) {
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
sendString(ps1);
sendString(ps2);
Console.ReadKey();
}
}
}
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau
The String is: Hello World
إرسال تعليق