Прескочи до съдържанието
Редактирай

Delegates

Delegates (Делегати)

Делегатите в C# са указатели към методи. Те позволяват методи да бъдат предавани като параметри и да се използват за създаване на събития.

Деклариране на делегат

// Прост делегат
public delegate void SimpleDelegate();

// Делегат с параметри
public delegate void MessageDelegate(string message);

// Делегат с връщана стойност
public delegate int CalculateDelegate(int x, int y);

Използване на делегати

public class Calculator
{
    public static int Add(int x, int y) => x + y;
    public static int Multiply(int x, int y) => x * y;

    public static void Main()
    {
        // Създаване на делегат
        CalculateDelegate calc = Add;
        
        // Извикване на делегат
        int result = calc(5, 3); // 8
        
        // Промяна на метода
        calc = Multiply;
        result = calc(5, 3); // 15
    }
}

Multicast делегати

public class Notifier
{
    public static void EmailNotify(string message)
    {
        Console.WriteLine($"Sending email: {message}");
    }

    public static void SMSNotify(string message)
    {
        Console.WriteLine($"Sending SMS: {message}");
    }

    public static void Main()
    {
        // Комбиниране на делегати
        MessageDelegate notify = EmailNotify;
        notify += SMSNotify;

        // Извиква и двата метода
        notify("Hello!");

        // Премахване на метод
        notify -= EmailNotify;
    }
}

Вградени делегати

Action<T>

// Делегат без връщана стойност
Action<string> print = Console.WriteLine;
print("Hello World");

// Action с множество параметри
Action<string, int> greet = (name, age) => 
    Console.WriteLine($"Hello {name}, you are {age} years old");
greet("John", 25);

Func<T>

// Делегат с връщана стойност
Func<int, int, int> add = (x, y) => x + y;
int sum = add(5, 3);

// Func с един параметър и връщана стойност
Func<string, int> getLength = str => str.Length;
int length = getLength("Hello");

Predicate<T>

// Делегат, който връща bool
Predicate<int> isEven = num => num % 2 == 0;
bool result = isEven(4); // true

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
List<int> evenNumbers = numbers.FindAll(isEven);

Анонимни методи

// Стар синтаксис (C# 2.0)
MessageDelegate oldStyle = delegate(string message)
{
    Console.WriteLine(message);
};

// Нов синтаксис с ламбда израз (C# 3.0+)
MessageDelegate newStyle = message => Console.WriteLine(message);

Събития и делегати

public class Button
{
    // Събитие, базирано на делегат
    public event EventHandler Click;

    public void OnClick()
    {
        Click?.Invoke(this, EventArgs.Empty);
    }
}

public class Program
{
    public static void Main()
    {
        Button button = new Button();
        
        // Абониране за събитието
        button.Click += (sender, e) => Console.WriteLine("Button clicked!");
        
        // Симулиране на клик
        button.OnClick();
    }
}

Асинхронни делегати

public class AsyncExample
{
    public delegate Task AsyncDelegate();

    public static async Task Main()
    {
        AsyncDelegate asyncWork = async () =>
        {
            await Task.Delay(1000);
            Console.WriteLine("Async work completed");
        };

        await asyncWork();
    }
}