Delegate
A delegate is a type that represents references to methods with a particular parameter list and return type.
class Program
{
    // Declaration
    public delegate int DelegateMethod(ref int x);
    public static int Add1(ref int x)
    {
        x += 1;
        return x;
    }
    public static int Multiple2(ref int x)
    {
        x *= 2;
        return x;
    }
    static void Main(string[] args)
    {
        DelegateMethod calculate;
        int x;
        x = 1;
        calculate = Add1;
        calculate?.Invoke(ref x); // 1 + 1 = 2
        Console.WriteLine(x); // 2
        x = 1;
        calculate += Multiple2; // Add other method
        calculate?.Invoke(ref x); // (1 + 1) * 2 = 4
        Console.WriteLine(x); // 4
    }
}
- If the delegate has a return value and/or out parameters, it returns the return value and parameters of the last method invoked
- Delegate can bind to instance
class Counter
{
    public int count = 0;
    public void Add()
    {
        count += 1;
    }
}
class Program
{
    // Declaration
    public delegate void DelegateMethod();
    static void Main(string[] args)
    {
        var a = new Counter();
        var b = new Counter();
        // Delegate does not need initialize, can be null
        DelegateMethod method = null;
        method = a.Add;
        // method += a.Add;
        // += can be use even delegate is null
        // Use ?. will not call if `method` is null
        method?.Invoke();
        Console.WriteLine(a.count); // 1
        method += b.Add;
        method?.Invoke();
        Console.WriteLine($"{a.count} {b.count}"); // 2 1
    }
}
Anonymous
var delegateFunction = delegate()
{
    // ...
    // return ...;
};
C# defined delegate
public delegate void Action();
public delegate void Action<in T>(T obj);
// ...
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
// ...
Lambda / Anonymous
With return value
Func<int, int> Add1 = (n) => n + 1;
// same as
Func<int, int> Add1 = (n) => { return n + 1; };
Without return value
Action<string> Hi = (name) =>
{
    Console.WriteLine($"Hi, {name}");
};
- Lambda is closure, that can access outer scope
int x = 1;
var doubleX = () =>
{
    return x * 2;
};
Console.WriteLine(doubleX());