Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Giải thích khái niệm Delegate trong C#

Nếu bạn lập trình C, delegate giống con trỏ hàm (function pointer). Nhưng delegate trong C# mạnh hơn nhiều. Bài viết giải thích khái niệm và ứng dụng thực tế.

Delegate cung cấp cấp độ gián tiếp (indirection). Nó đóng gói đoạn code có thể truyền quanh và thực thi type-safe. Thay vì thực thi hành vi ngay, hành vi bị chứa trong đối tượng. Có nhiều hành động trên đối tượng đó, một trong số là thực thi hành vi bên trong.

Delegate cho phép viết higher-order functions: hàm nhận hàm làm tham số hoặc trả về hàm. Kiểu delegate định nghĩa chữ ký phương thức: kiểu trả về và kiểu tham số. Ví dụ Transformer đại diện cho method nhận và trả về int:

delegate int Transformer(int x);

Gán method (lambda, instance, static) thỏa chữ ký:


Transformer square = x => x * x;
Transformer cube = x => x * x * x;
Console.WriteLine(square(3)); // 9
Console.WriteLine(cube(5));   // 125

Khi nào dùng Delegate?

Khi code muốn thực thi hành động nhưng không biết chi tiết hành động đó, chỉ biết interface của nó. Thường gặp khi cần thực thi hành động cụ thể nhưng không biết trước sẽ gọi method nào. Delegate giải quyết bằng cách thay hành vi bằng delegate instance phù hợp với ngữ cảnh.

4 bước để Delegate hoạt động

1. Khai báo kiểu Delegate

Định nghĩa chữ ký hàm: kiểu tham số và kiểu trả về.

delegate int Processor(int numOne, int numTwo);

2. Code thực thi trong method

Định nghĩa method cùng chữ ký delegate:


static int Add(int numOne, int numTwo) => numOne + numTwo;
static int Subtract(int numOne, int numTwo) => numOne - numTwo;

3. Tạo instance Delegate

Gán method cho delegate instance:


Processor processorOne = new Processor(Add);
Processor processorTwo = new Processor(Subtract);

4. Gọi (Invoke) Delegate

Gọi method Invoke hoặc gọi trực tiếp như method:


int sum = processorOne.Invoke(3, 5);     // 8
int difference = processorTwo(10, 6);    // 4

Kết hợp và loại bỏ Delegate

System.Delegate có 2 static method: Combine và Remove.

Combine

Tạo delegate mới với invocation list nối đuôi nhau. Khi invoke, các action chạy theo thứ tự. Nếu action nào ném exception → các action sau không chạy.


public static Delegate Combine(params Delegate[] delegates);
// hoặc
public static Delegate Combine(Delegate a, Delegate b);

Remove

Loại bỏ lần xuất hiện cuối của invocation list của delegate này từ delegate kia. Trả về delegate mới.


public static Delegate Remove(Delegate source, Delegate value);

Tóm tắt

  • Delegate đóng gói hành vi với kiểu và tham số cụ thể, giống interface 1 method.
  • Chữ ký delegate xác định method nào có thể tạo instance và chữ ký invoke.
  • Tạo instance cần method muốn thực thi khi invoke.
  • Delegate instance bất biến (immutable), giống string.
  • Mỗi instance chứa invocation list (danh sách action).
  • Có thể Combine và Remove delegate lẫn nhau.

Ví dụ hoàn chỉnh

using System;

class Program
{
    delegate int Transformer(int x);
    delegate int Processor(int numOne, int numTwo);

    static void Main()
    {
        Transformer square = x => x * x;
        Transformer cube = x => x * x * x;
        Console.WriteLine(square(3)); // 9
        Console.WriteLine(cube(5));   // 125

        Processor processorOne = new Processor(Add);
        Processor processorTwo = new Processor(Subtract);
        int sum = processorOne.Invoke(3, 5);
        Console.WriteLine(sum); // 8
        int difference = processorTwo(10, 6);
        Console.WriteLine(difference); // 4
    }

    static int Add(int numOne, int numTwo) => numOne + numTwo;
    static int Subtract(int numOne, int numTwo) => numOne - numTwo;
}

Kết quả đầu ra

9
125
8
4