跳到主要内容

Delegates, Events, Func, Action, Lambda

Short, interview-ready summary.


Memory hook

"Delegate = type-safe method reference; event = encapsulated delegate; Func/Action = built-in delegate types; lambda = inline delegate"


Delegate (type-safe method pointer)

public delegate int BinaryOp(int a, int b);

BinaryOp add = (a, b) => a + b;
int result = add(2, 3); // 5

// Or assign method
int Sum(int a, int b) => a + b;
BinaryOp op = Sum;
  • Delegate type defines signature (params + return type)
  • Instance can point to any method (or lambda) that matches

Func and Action (built-in delegate types)

// Func<TResult> or Func<T1, T2, ..., TResult> — has return value
Func<int, int, int> add = (a, b) => a + b;
Func<string> getMessage = () => "Hello";

// Action or Action<T1, T2, ...> — no return (void)
Action<string> log = msg => Console.WriteLine(msg);
Action noArg = () => Console.WriteLine("Done");
  • Func — last type parameter is return type
  • Action — void return

Lambda expressions

// Expression lambda (single expression)
Func & lt;
(int, int & gt);
square = (x) => x * x;

// Statement lambda (block)
Action & lt;
int & gt;
print = (x) => {
Console.WriteLine(x);
};

// Multiple parameters
Func & lt;
(int, int, int & gt);
sum = (a, b) => a + b;

// No parameters (discarded)
Func & lt;
int & gt;
getRandom = () => Random.Shared.Next();
  • => separates parameters from body
  • Parentheses required for zero or multiple parameters: () => 1, (a, b) => a + b

Event (encapsulated delegate)

"Event = delegate that only the declaring class can invoke"

public class Button
{
public event EventHandler? Clicked;

protected virtual void OnClicked()
{
Clicked?.Invoke(this, EventArgs.Empty);
}
}

// Subscriber
button.Clicked += (sender, e) => Console.WriteLine("Clicked");
button.Clicked -= handler; // unsubscribe
  • event allows only += and -= from outside; prevents null assignment and direct invoke
  • Convention: (object? sender, EventArgs e)
  • Use ?.Invoke() to avoid null reference

Multicast delegate

  • One delegate instance can hold multiple methods (+=)
  • Invocation calls all in order
  • Return value: only last method’s return (usually use void / Action for multicast)

Interview one-liner

"A delegate is a type-safe reference to a method. Func and Action are generic delegate types for methods with and without return values. Lambdas are inline anonymous methods. Events are delegates exposed with +=/-= only, so subscribers can’t invoke or replace the list."


Cheat sheet

Delegate = method reference type
Func<T1, T2, TResult> = (T1, T2) → TResult
Action<T> = T → void
Lambda = (params) => expression-or-block
event = delegate with +=/-= only