From delegates to callbacks, events, LINQ and async
A delegateDelegatesA type-safe function pointer, so a method can be passed around like any other value.Opens in a new tab holds a method. Each of these adds one thing to that.
Callbacks
A callback is a delegate called later. The method calls it back without knowing what it does.
void DownloadFile(string url, Action<string> onComplete){ // ... download logic ... onComplete("File downloaded!"); // call back into the caller's code} DownloadFile("http://x.com", message => Console.WriteLine(message));Events
An event is a protected list of delegates: it can hold several methods, only the owning class can invoke it, and outside code can only subscribe (+=) or unsubscribe (-=). See eventsEventsHow a class tells other classes that something happened, without knowing who is listening.Opens in a new tab.
class Button{ public event Action Clicked; // a delegate field, but restricted public void Click() { Clicked?.Invoke(); // fires all subscribed methods }} Button b = new Button();b.Clicked += () => Console.WriteLine("Handler 1");b.Clicked += () => Console.WriteLine("Handler 2");b.Click(); // both runLINQ
Where takes a Func<int, bool> and Select a Func<int, int>. Each LINQ method applies a delegate to every element (see LINQLINQ: query syntax and method syntaxOne SQL-like way to query many kinds of data, written in two equivalent forms.Opens in a new tab).
async and await
Before async/await, asynchronous code used raw callbacks. await is compiler-generated continuation logic: run the next chunk when the async work finishes. It is implemented as a state machine (see how await worksHow await works under the hoodThe compiler turns an async method into a state machine, and the thread is freed while it waits.Opens in a new tab).
async Task Run(){ string data = await DownloadFileAsync(url); Console.WriteLine(data);}