Delegates are used when you want save the method address in a variable, and call via the variable rather than by the name. Many languages have an address of operator, but methods call are highly typed. When you declare a delegate variable, it meant to both define the method signature and store the value, the delegate type overrides the plus operator to allow adding multiple callbacks.
originally you needed to define the delegate type before using, but after generics were added, the handy Func<> and Action<> generics can be used to define a delegate variable.
Action<string> myCallback; // variable to hold address of a method that take a string value
Methods need to named members of a class. Lambda are a way to define an anonymous method, that is one without name. As they don’t have a name, the definition of a lambda returns a variable that can be used as a delegate variable. In other words a lambda defines an expression that return a lambda, rather than a method definition.
For example:
myCallback = s => Console.WriteLine(s);
then later call:
myCallback(“hello”);
note: lambda also implement closure, which is very handy in callbacks, and often makes more useful than defined methods.