# Delegate

Delegate is a special data type in C# used to declare references to functions or methods (Can be understood as a pointer to a function). When assigning a function or method to a delegate, the delegate will point the reference to that function or method. Then instead of calling the function directly, we can use the delegate to call it without knowing the function name. Delegates make calling functions more flexible.

```csharp
using System;

delegate int CalculatorDelegate(int num1, int num2);

class Program {
    static void Main(string[] args) {
        // Initialize
        CalculatorDelegate calculatorDelegate = new CalculatorDelegate(MaxNumber);

        // Call a method through delegate
        int result = calculatorDelegate(10, 20);

        // Print result
        Console.WriteLine("Max number: " + result);
    }

    static int MaxNumber(int num1, int num2) {
        return (num1 > num2) ? num1 : num2;
    }
}
```

* In the example above, instead of calling the MaxNumber function directly to find the largest of the two numbers, we call the delegate variable calculatorDelegate.

#### Use delegates to call different functions <a href="#id-2-su-dung-delegate-goi-toi-cac-ham-khac-nhau-1" id="id-2-su-dung-delegate-goi-toi-cac-ham-khac-nhau-1"></a>

```csharp
using System;

// Khai báo delegate
delegate int Calculator(int a, int b);

class Program {
    static int Add(int a, int b) {
        return a + b;
    }

    static int Subtract(int a, int b) {
        return a - b;
    }

    static void Main(string[] args) {
        // Create instance of delegate, pass method Add into delegate
        Calculator calculator = new Calculator(Add);

        // Using delegate to calculate sum of 2 number
        int result = calculator(10, 5);
        Console.WriteLine("10 + 5 = " + result);

        // Pass Subtract method into delegate
        calculator = new Calculator(Subtract);

        // Using delegate to calculate subtract of 2 number
        result = calculator(10, 5);
        Console.WriteLine("10 - 5 = " + result);

        Console.ReadKey();
    }
}

```

* In the above example, we use the calculator delegate to call the Add method if we assign calculator = new Calculator(Add); Call the Subtract method if we assign calculator = new Calculator(Subtract);.
* By using the same delegate to call different functions, we see that calling functions is very flexible and easy.

#### Use the delegate to create a callback <a href="#id-3-su-dung-delegate-de-tao-ra-mot-callback-2" id="id-3-su-dung-delegate-de-tao-ra-mot-callback-2"></a>

```csharp
using System;

delegate void Callback(string message);

class Program
{
    static void Main(string[] args)
    {
        CallMethodWithCallback("Hello, world!", DisplayMessage);
    }

    static void CallMethodWithCallback(string message, Callback callback)
    {
        Console.WriteLine("Method called with message: " + message);
        callback(message);
    }

    static void DisplayMessage(string message)
    {
        Console.WriteLine("Callback called with message: " + message);
    }
}
```

* In the example above, we see that we will declare a callback with delegate delegate void Callback(string message);. When we call the function CallMethodWithCallback we can pass the function as a parameter: CallMethodWithCallback("Hello, world!", DisplayMessage);
* The above example will produce the following result:

```
Method called with message: Hello, world!
Callback called with message: Hello, world!
```

#### Use delegates in Lambda Expression <a href="#id-4-su-dung-delegate-trong-lambda-expression-3" id="id-4-su-dung-delegate-trong-lambda-expression-3"></a>

```csharp
delegate int Operation(int a, int b); // Initialize delegate

class Program
{
    static void Main(string[] args)
    {
        Operation sum = (a, b) => a + b;
        Operation product = (a, b) => a * b;

        int x = 5, y = 3;
        Console.WriteLine($"Tổng của {x} và {y} là {sum(x, y)}"); // Result: 8
        Console.WriteLine($"Tích của {x} và {y} là {product(x, y)}"); // Result: 15
    }
}
```

```csharp
class Program
{
    static int Sum(int x, int y)
    {
        return x + y;
    }

    static void Main(string[] args)
    {
        Func<int,int, int> add = Sum;

        int result = add(10, 10);

        Console.WriteLine(result); 
    }
}
```

* Func\<int, int, int> is a delegate of type int with 2 parameters passed in int type.
