
Delegates trong C# – Công cụ mạnh mẽ cho lập trình viên
May 17, 2025Bài viết trước mình đã đề cập đến Func, Action, Predicate đi liền với Expression bạn có thể đọc lại: https://blog.ntechdevelopers.com/func-vs-predicate-vs-expression-trong-c-net/
Ở bài viết này cũng với các từ khóa đó nhưng mình sẽ đi sâu vào bản chất delegate của chúng
Delegates là một tính năng quan trọng giúp nâng cao sức mạnh của C#. Chúng cho phép chúng ta truyền phương thức như một tham số, lưu trữ phương thức như một biến, và tạo ra các sự kiện hoặc callback tùy chỉnh.
- Func: Đại diện cho phương thức nhận 0 hoặc nhiều tham số và trả về một giá trị bất kỳ.
- Action: Đại diện cho phương thức nhận 0 hoặc nhiều tham số nhưng không trả về giá trị.
- Predicate: Đại diện cho phương thức nhận một tham số duy nhất và trả về giá trị kiểu
bool
.

Trong thế giới phát triển .NET, Delegates, Func, Action và Predicate là những công cụ mạnh mẽ giúp viết mã linh hoạt và tái sử dụng cao. Mặc dù thoạt nhìn có vẻ giống nhau, nhưng mỗi loại lại có mục đích và cách sử dụng riêng biệt. Bài viết này sẽ giúp bạn hiểu rõ sự khác biệt giữa chúng và cách áp dụng hiệu quả trong thực tế.
1. Delegates: Nền tảng của Callback
Delegates là kiểu tham chiếu có thể lưu trữ tham chiếu đến các phương thức có cùng chữ ký. Điều này cho phép chúng ta truyền phương thức như một tham số, giúp việc gọi phương thức trở nên linh hoạt hơn.
Ví dụ:
// Khai báo delegate
delegate void MyDelegate(int number);
// Phương thức phù hợp với delegate
static void PrintNumber(int number)
{
Console.WriteLine($"The number is {number}");
}
// Phương thức nhận delegate làm tham số
static void InvokeDelegate(MyDelegate del, int number)
{
del(number);
}
// Sử dụng
InvokeDelegate(PrintNumber, 42);
Ở đoạn code trên, MyDelegate
là một delegate nhận tham số int
và không trả về giá trị. Chúng ta truyền phương thức PrintNumber
vào InvokeDelegate
, tạo ra hành vi callback.
2. Func: Delegate cho phương thức có giá trị trả về
Func<T>
là một delegate generic giúp chúng ta đại diện cho một phương thức có thể nhận đến 16 tham số và trả về một giá trị.
Ví dụ:
// Phương thức tính bình phương
static int Square(int number)
{
return number * number;
}
// Phương thức sử dụng Func
static int PerformOperation(Func<int, int> operation, int number)
{
return operation(number);
}
// Sử dụng
int result = PerformOperation(Square, 5);
Console.WriteLine(result); // Output: 25
Ở đây, Func<int, int>
đại diện cho một phương thức nhận một int
và trả về int
. Bằng cách truyền Square
vào PerformOperation
, chúng ta có thể dễ dàng thực hiện phép toán.
3. Action: Delegate cho phương thức không có giá trị trả về
Action<T>
đại diện cho một phương thức không có giá trị trả về nhưng có thể nhận nhiều tham số.
Ví dụ:
// Phương thức in ra màn hình
static void PrintMessage(string message)
{
Console.WriteLine(message);
}
// Phương thức sử dụng Action
static void PerformOperation(Action<string> operation, string message)
{
operation(message);
}
// Sử dụng
PerformOperation(PrintMessage, "Hello, World!");
Ở đây, Action<string>
đại diện cho một phương thức nhận string
nhưng không trả về giá trị.
4. Predicate: Delegate kiểm tra điều kiện
Predicate<T>
là một delegate đặc biệt nhận một tham số và trả về bool
, thường dùng để lọc dữ liệu hoặc kiểm tra điều kiện.
Ví dụ:
// Phương thức kiểm tra số chẵn
static bool IsEven(int number)
{
return number % 2 == 0;
}
// Phương thức sử dụng Predicate
static bool PerformOperation(Predicate<int> operation, int number)
{
return operation(number);
}
// Sử dụng
bool isEven = PerformOperation(IsEven, 6);
Console.WriteLine(isEven); // Output: True
5. Truyền Delegates như một tham số
Việc truyền delegate giúp mã linh hoạt hơn, hỗ trợ mô hình lập trình hướng sự kiện và xử lý động.
Một số lưu ý quan trọng khi truyền delegate:
- Kiểm tra
null
trước khi gọi delegate để tránhNullReferenceException
. - Đảm bảo chữ ký phương thức phù hợp với delegate.
- Thứ tự thực thi khi truyền nhiều delegate.
Ví dụ:
delegate void MyDelegate();
static void MethodA()
{
Console.WriteLine("Method A");
}
static void MethodB()
{
Console.WriteLine("Method B");
}
static void InvokeDelegates(params MyDelegate[] delegates)
{
foreach (var del in delegates)
{
del?.Invoke();
}
}
// Sử dụng
InvokeDelegates(MethodA, MethodB);
Kết quả:
Method A
Method B
Delegates, Func, Action và Predicate là những công cụ quan trọng trong lập trình .NET giúp viết mã linh hoạt và tái sử dụng cao. Hiểu và sử dụng tốt chúng sẽ giúp bạn làm chủ các mô hình lập trình callback, xử lý động và tối ưu hiệu suất hệ thống.