Delegate ใน C# คือตัวแปรชนิดอ้างอิง (reference type) ที่เก็บการอ้างอิงไปยังเมธอด สามารถเปลี่ยนการอ้างอิงไปยังเมธอดอื่นได้ในขณะรันไทม์ (runtime) Delegate ใช้เป็นพื้นฐานสำคัญของระบบ Event และ Callback methods ทุก Delegate มาจากคลาส System.Delegate โดยอัตโนมัติ
รูปแบบการประกาศ Delegate
delegate <return type> <delegate-name>(<parameter list>);
ตัวอย่างการใช้งาน Delegate แบบสมบูรณ์
using System;
using System.IO;
namespace DelegateAppl {
class PrintString {
static FileStream fs;
static StreamWriter sw;
// ประกาศ delegate
public delegate void PrintStringDelegate(string s);
// เมธอดพิมพ์หน้าจอ
public static void WriteToScreen(string str) {
Console.WriteLine("The String is: {0}", str);
}
// เมธอดเขียนไฟล์
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();
}
// เมธอดรับ delegate เป็นพารามิเตอร์
public static void SendString(PrintStringDelegate ps) {
ps("Hello World");
}
static void Main(string[] args) {
PrintStringDelegate ps1 = new PrintStringDelegate(WriteToScreen);
PrintStringDelegate ps2 = new PrintStringDelegate(WriteToFile);
SendString(ps1);
SendString(ps2);
Console.ReadKey();
}
}
}
ผลลัพธ์
The String is: Hello World
(และข้อความ "Hello World" จะถูกเขียนลงไฟล์ c:\message.txt ด้วย)
คุณสมบัติสำคัญของ Delegate
- Type-safe - ตรวจสอบลายเซ็นเมธอดที่คอมไพล์ไทม์
- Multicast - ใช้
+หรือ+=รวม delegate หลายตัวได้ เรียกตามลำดับ - Covariance/Contravariance - รองรับการแปลงชนิดข้อมูลในพารามิเตอร์และค่าคืน
Multicast Delegate ตัวอย่าง
PrintStringDelegate multi = WriteToScreen;
multi += WriteToFile; // รวม 2 เมธอด
multi("Hello"); // เรียกทั้งคู่ตามลำดับ
Func และ Action (Built-in Delegates)
.NET มี delegate สำเร็จรูปให้ใช้งานทันที:
Action- ไม่มีค่าคืน (void) รองรับถึง 16 พารามิเตอร์Func<TResult>- มีค่าคืน รองรับถึง 16 พารามิเตอร์Predicate<T>- คืนค่า bool ใช้กับการกรองข้อมูล
Action print = Console.WriteLine;
Func add = (a, b) => a + b;
Predicate isEven = x => x % 2 == 0;