Delegates, Events & Lambdas

লেসন ১৩ / ৫০

Delegate কী?

Function কে variable হিসেবে pass করার type-safe pointer।

// 1. Declare
public delegate int MathOp(int a, int b);

// 2. Method
public static int Add(int a, int b) => a + b;
public static int Mul(int a, int b) => a * b;

// 3. Use
MathOp op = Add;
Console.WriteLine(op(3, 4));    // 7

op = Mul;
Console.WriteLine(op(3, 4));    // 12

Func, Action, Predicate ⭐

// Action — void return
Action<string> print = msg => Console.WriteLine(msg);
print("Hello");

Action<int, int> show = (a, b) => Console.WriteLine(a + b);

// Func<..., TReturn> — last is return type
Func<int, int, int> add = (a, b) => a + b;
int result = add(3, 4);    // 7

Func<string, int> len = s => s.Length;

// Predicate<T> — Func<T, bool> এর shortcut
Predicate<int> isEven = n => n % 2 == 0;
bool e = isEven(4);    // true

Lambda Syntax

// (params) => body
x => x * 2
(x, y) => x + y
() => "Hello"
x => { return x * 2; }    // statement body

// LINQ এ ব্যবহার
var evens = nums.Where(n => n % 2 == 0);

Multi-cast Delegate

Action<string> logger = Console.WriteLine;
logger += msg => File.AppendAllText("log.txt", msg);
logger += msg => Database.Log(msg);

logger("Error!");    // তিনটিই execute

Event ⭐

// Publisher
public class Button {
    public event EventHandler<ClickEventArgs> Clicked;

    public void OnClick() {
        Clicked?.Invoke(this, new ClickEventArgs { Time = DateTime.Now });
    }
}

public class ClickEventArgs : EventArgs {
    public DateTime Time { get; set; }
}

// Subscriber
var btn = new Button();
btn.Clicked += (sender, e) => Console.WriteLine($"Clicked at {e.Time}");

btn.OnClick();

Closure

int counter = 0;
Action increment = () => counter++;    // capture outer variable

increment();
increment();
Console.WriteLine(counter);    // 2

Real Use Case — Callback

public async Task DownloadAsync(string url, Action<int> onProgress) {
    for (int i = 0; i <= 100; i += 10) {
        await Task.Delay(100);
        onProgress(i);
    }
}

await DownloadAsync("...", percent => {
    Console.WriteLine($"{percent}%");
});