Delegates
As described in my textbook, delegates are basically just an alias for a method (or "function" for you VB noobs). It is abstract and can basically be used the same as any method with the same signature (or parameters). You declare these the same as you would most any variable --
Example:
delegate int MyDelegate(int a);
So what you're saying here is that you're creating a delegate method that will return an int and accepts an int as an arguement. Ok, so wheres the body of this method? Well like I said, it's abstract so you don't define it here. So wtf do you do with this? The best way I can think of explaining the use for this (at least at this level) is that declaring a delegate is almost like declaring a new datatype, kinda like you're creating a class. But why? For the sole purpose of being able to pass it as an argument. Yes, so that you can pass a method to another method as an argument. This sounds goofy, so let's just make an example --
Lets say you have a simple method that adds 1 to any number passed to it:
private int AddOne(int number){ return number + 1;}
Ok, simple enough. The method accepts an integer, adds 1 to it and sends it back. Now let's say that you had another method that accepts an array of integers adds 1 to each integer and prints it out; we will use an IEnumerable parameter so that we can enumerate through the collection:
private void PrintNumberPlusOne(IEnumerable<int> numbers){ foreach(int number in numbers) { Console.WriteLine(number + 1); }}
Ok, so this is probably the way a normal person would solve that problem (print out the number plus 1), but I'm only using this for the purpose of illustration. Here is another way we could do it using our delegate:
private void PrintNumberPlusOne(IEnumerable<int> numbers, MyDelegate del){ foreach(int number in numbers) { Console.WriteLine(del(number)); }}
Ok, holy shit. What just happened here? Instead of writing the code (number +1) into the WriteLine method, I used the delegate. By including MyDelegate as the datatype for del, the PrintNumberPlusOne method accepts a delegate as an arguement. But not just any delegate; the delegate called MyDelegate which we declared earlier. This is important because we defined that delegate to accept one argument in the form of an integer and returns an integer, remember? So now, we can pass ANY method into this method so long as it takes a single integer as an argument and returns an int. So the call to the PrintNumberPlusOne method would looks like this:
int[] numbers = new int[]{ ... }; PrintNumberPlusOne(numbers, AddOne);
so we're calling the PrintNumberPlusOne method and sending the array "numbers" along with the method "AddOne". Make sense? Why would you do this? Well in keeping with good design, you want to stay loosely coupled, meaning you want the method to become dependent on the function inside of it as little as possible. What if you wanted it to add 2 and then divide by 1? Sure that's simple in this scenario, but when the function becomes more complex, that could get messy. The other reason is that this is a form of anonymous method. If you don't know what that is, then you should look it up; it's a completely different topic of its own.
Ok, so we got that out of the way. So what is a Lambda?
Lambda Expressions
A lambda expression is basically a delegate without all the mess. If your function is simple, you can pass it to another method inline vs. having to code a method separately, so long as the method your passing to still accepts a delegate. So let's use our example from above. Here is the lambda in action:
PrintNumberPlusOne(number, x => x + 1);
This syntax has eliminated the need for the "AddOne" method. This looks kind of funny so lets break that down:
The original AddOne method received a single argument. It then took that argument and added 1.
x => x + 1 //is read "x goes to x plus one"
the items on the left of the lambda operator are the same as defining the parameters of the original method. Everything on the right of the lambda operator are the actual function itself. Let's see that side by side:
private int AddOne(int number){ return number + 1;}
is the same as:
number => number + 1
Isn't that elegant?
So when would you use this shortcut? If the method is simple and isn't going to be reused anywhere else in your code, then this is the best way to do. If you have other methods that are going to use this, then you might want to use the traditional delegate technique. But this is best for one time use. This is one of a few ways to use lambdas. This begins to get a lot more useful when combined with LINQ. You can literally condense a 10 line SQL statement down to just a few by using this (http://msdn.microsoft.com/en-us/library/bb397675.aspx).
Anyway. I wrote this as notes to myself, but I hope this can help someone else out there!