It's a much more concise form of method notation. The following are roughly equivalent:
// explicit method
int MyFunc(int x) {
return x;
}
// anonymous (name-less) method
// note that the method is "wrapped" up in a hidden object (Delegate) this way
// so there is a very tiny bit of overhead compared to an explicit method
// (though it's really the assignment that causes that and would also happen
// if you assigned an explicit method to a reference)
Func<int, int> MyFunc =
delegate (int x) { return x; };
// lambda expression (also anonymous)
// basically identical to anonymous method,
// except with everything inferred as much as possible, intended to be minimally verbose
Func<int, int> MyFunc =
x => x;
// and => is now also used for "expression-bodied" methods
// which let you omit the return keyword and braces if you can evaluate
// to something in one line
int MyFunc(int x) =>
x;
Think of a lambda expression as saying, "given something, return something". In the example above, the lambda expression x => x
says "given x, return x", although lambda expressions don't necessarily need to return something, in which case you might read them as "given x, do something with x".
Also note that there are kind of three things called "delegate" which can be very confusing at first.
An anonymous method uses the delegate
keyword, but defines a method with no name:
Func<int, int> = delegate (int x) { return x; };
Assigning a method (anonymous, explicit, or lambda) to a reference causes a hidden Delegate
wrapper object to be created that is what allows the method to be referred to. (Basically a sort of "managed function pointer".)
And then, you can also declare named method signatures using the delegate
keyword as well:
public delegate int TestFunc(int x, int y);
TestFunc myFunc = delegate (int x, int y) { return x + y; };
This declares a named signature TestFunc
that takes two int
s and returns an int
, and then declares a delegate reference of that type which is then assigned an anonymous method with matching signature.