JeremyBytes - C# Delegates - Part 2: Getting Func-y (+ Lambdas)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this is Jeremy Clarke of Jeremy bytes calm and today we're going to continue our look at c-sharp delegates this time we're going to be getting a little funky we're going to look at one of the built-in delegate types func of T and we'll also see how lambda expressions fit into the picture of delegates as well now just as a quick review a delegate is a type that defines a method signature this means that instead of defining data and method implementations like most of our other types this just defines the method signature so the parameters and the return type for a particular method now why do we care about delegates well as we saw last time they allow us to decouple our code this can give us extension points in two classes without having to modify the classes themselves and we can use methods as parameters again this is known as a higher-order function a function that takes another function as a parameter in addition delegates have multicast capability so we can run more than one method by invoking a single delegate and we can use them in callbacks and event handlers and we see them frequently in Lync now today we're going to take a little bit of a detour to show how we can use the built-in delegate type func of T and we'll also see how lambda expressions fit in with delegates so let's jump over to the code so as a reminder let's look at how we left our application if we run our application we see we have a list of person on the left hand side then in the middle we have some string handling options and then we have a process data button and when we click process data we'll see our output box shows whatever string handling method we chose so our default value is first name space last name our last name is last name to uppercase first name does first name to lowercase and full-name does last name comma first name and again these decisions can be made at runtime because we have a delegate inside of our person class so as a reminder of what we have here we do have a custom delegate type that we created called person format and this declares a method that takes a person as a parameter and returns a string and we actually use this delegate type as a parameter inside a two string method on our person class so this allows us to inject any method that we want as long as it takes a person as a parameter and returns a string as a result by doing this we can change the functionality of our person class without having to modify the class itself and then back in our code behind we see how we select our different methods so at the top of our class we have a person format variable called format person and then our assigned delegate method we'll assign a particular method to our variable based on which radio buttons checked and as our last step we loop through all of our person objects in our list we call to string on them and we pass in our format person variable now this is all well and good but there's actually an easier way that we can do this starting with dotnet 3.5 we got some built-in delegate types one of those is func of T so let's go to help and look that up and so here we are looking at func of T T result now this isn't anything special all it is is a predefined delegate types that uses generic type parameters if you want more information on generic type parameters I do have another video series on c-sharp generics now func of TT result is pretty easy to parse so T result is actually the type of our return value and T is the type for our parameter that's coming in and to show how this relates to our custom type let's put them side-by-side so here's our custom one public delegate string person format person input so if we put in the definition for our func of TT result we have public delegate t result func of n t out t results and then tea argh so let's go ahead and move these around a little bit so that our parameters and types line up so we see the Declaration of funk is very close to our declaration for person format instead of string as the return value we have a generic type T result and instead of person as a parameter we have a generic type T now because funk uses generics that means that we can substitute this with whatever types that we need and that means we don't actually have to create this custom type so rather than using the custom type we can just use funk instead so let's go down to our to string method and instead of using person format will say funk and we'll use this overload that takes one parameter so our parameter type is person and our return type is string so what we have now is a delegate that matches the same signature that we had before so it takes a person as a parameter and returns a string as a result but instead of creating a custom type we can just use the built-in funk that we have in dotnet so now that we've changed our code we'll need to make some modifications to our code behind in our class now this person format type no longer exists but we can create a variable of type funk of person string called format person and everything else stays exactly the same we have the same method signature we're taking a person as a parameter and returning a string that means the assignments of all of the methods that we have before still work and we don't need to make any other changes to our code and if we run our application we'll see that it works exactly the same way so we have our default we have our last name two upper our first name two lower and our last name comma first name so we haven't changed functionality at all now why should we use funk over creating a custom delegate type well first of all because it's there if I can avoid creating a custom type and I can use one that's already in the box then I want to use that but more importantly I really like using funk because it gives us all of the information that we need so let's go down to our to string method now if we ask for help of what the type is for this previously we had something that just said person format well that doesn't tell me anything about the type and I probably need to click over back to the person class look at what this person format type is oh it's a delegate that takes a person and returns a string but now that we have funk in here I have all of the information I need right here okay so this is a funk of person string that means it takes a person as a parameter and returns a string and this makes it much much easier to figure out what I need to use is a parameter for this method now there are some subtler reasons we don't want to use custom types as well if we create two different custom types even if the method signature matches there's still different types so we're not able to assign one to the other without doing some additional code but when we're dealing with funk of persons string anything that matches the signature is assignable to this format person variable and at the same time any method that matches this signature can be used as a parameter for our two string method now you might ask what if we have more parameters well if we go back to our help file we'll see there is also a funk of t1 t2 result so this takes two parameters and returns a value and net 3.5 we got T 1 T 2 T 3 T 4 T result so we could have up to four parameters now I guess someone decided that four parameters wasn't enough because in dotnet 4.0 we got this one yes this actually defines a method that takes 16 parameters now I was really really hoping that in dotnet 4.5 we'd get one that would take 64 parameters but I guess that didn't happen now if you do find yourself creating a method that has 16 parameters you might want to ask a friend to take a look at it but we do have that option available so funk will take between 1 & 16 / M and there is actually a funk that doesn't take any parameters at all it just has a return value now anyone who knows me knows that I really love lambda expressions and wherever I see funk in my code I treat that as a big flashing sign that says put your lambda expression here now a lambda expression is simply an anonymous delegate which means wherever we see func we can replace it with a lambda expression now if you want some more information on the anatomy of a lambda expression I do have a video on my channel called anatomy of a lambda expression here we'll just go through the short version now what we have now are known as named delegates so for example in our option one button section we have a named delegate called for matters dot default that we assign to that format person variable now if we click into for matters default we see that it's simply a method that conforms to our signature so it takes a person as a parameter and it returns a string value now rather than using a named delegate we can convert this into an anonymous delegate well what's an anonymous delegate it's simply a delegate without a name let me show you how we can do that so I'm going to take the parameters and the method body highlight that and say ctrl C to copy and then we'll go back over to our code and instead of assigning to this formatters default I'm going to use the delegate keyword and then paste so you can see I have a delegate keyword then our parameter which is person input and then the method body inside the curly braces and I can actually do this with the rest of our delegates as well so we'll take last name two upper come back here we'll use the delegate keyword and paste and then here's first name to lower and then the delegate keyword and paste and then finally we have the full name so we'll just copy this over use the delegate keyword and paste so what we've just done is inline all of our methods and just to show that we don't need our other methods anymore I'm going to comment out this entire class so I'm just going to say control Casey to comment that out and now when we rerun our application we'll see that it still works exactly the same way it did before so we have our default our last name - upper our first name - lower and our last name comma first name so we haven't affected the functionality at all now I mentioned that a lambda expression is simply an anonymous delegate well we have anonymous delegates here so let's change them to lambda expressions all we have to do to change a delegate to a lambda expression is remove the delegate keyword and then put the lambda operator in between the parameters and the method body and again the lambda operator is just this funky equal greater than sign so we'll add that to all of our methods and now we have lambda expressions and as you might expect our application works exactly the same way that it did before so we can see that all of our values are still coming out as expected now lambda spreche UNS have the advantage of having some syntactic sugar that we can use to make them very very compact now the first thing is known as parameter type inference what that means is that if the compiler can figure out the type of the parameter we don't have to type it in so I can remove this person keyword from our parameters now if we have our over input we see that it is still strongly typed so it is still of type person now the reason the compiler can figure this out is because this is the only thing we're allowed to assign to our format person variable again is our format person well it's a funk of person string which means it does have to take a person as a parameter if we try to assign anything else we get an error now another thing about lambdak spreche ins is if we have a single parameter we don't need parentheses around it so we can just have input just like this now as a convention people generally use single character parameter names for land expressions so we can change the input to just P and that will stand for person and to make things more compact because we have an expression lambda which returns a value we actually don't need the return keyword and we don't need these curly braces either so I can actually delete all of this now what we're left with is P our parameter and again this is strongly typed it is of type person and then we have our lambda operator and then we say p 2 string calling our default to string method so we can see that lambda expressions can make things very very compact let's do this with our next method and again I'll take this one step by step so we can remove the person keyword because our compiler can figure this out we can remove the parentheses since we only have one parameter we can rename our parameter to a single character and again that's just a convention it's not required and then we can remove the curly braces and the return statement so if we do this with all of our methods we come up with something extremely compact and just to show you that this still works the same way let's run our application and we'll see we have our default our last name - upper our first name - lower and our full name our last name comma first name so this is why I think lambda expressions are really really cool in this case before we switched over to lambdas our first option was assigning format person to formatters default that meant that we had to go to an entirely different class to see what that method actually does and these methods are very simple they're all just one-liners instead of going to a separate class now all of these methods are inline and the code is very compact and we can see exactly what's going on so for our second option we're taking the last name property and converting it to uppercase for a third option we're taking the first name converting it to lowercase and for the last option we're doing a string dot format to get last name comma first name now I am a huge fan of lambdak spreche ins and also link so you might want to take a look at my website and I have a presentation called learn to love lambdas which dives into this a bit more so what we've seen today is that rather than creating a custom delegate type called person format like we had before we can simply use the built-in funk of TT result as our type and fill in the generic types that we want so if we want a method that takes a person as a parameter and returns a string we can just say func of person string and we don't have to modify any of the other calling code now back in our class we did have to modify our variable so instead of our format person being of type person format it's now of type func of person string and again I really like having that here because this tells me exactly what format person is it needs to represent a method that takes a person as a parameter and returns a string result and we saw how we could swap out our delegates for lambda expressions now a lambda expression is simply an anonymous delegate so if we take our name to delegate and end I knit that creates an anonymous delegate and then we can switch over to the lambda expression and take advantage of a lot of the syntactic sugar to make very compact code so instead of having to have a separate formatted class with all of the methods in it I just have all of the methods in line in a very easy to read format now I know some people debate the easy to read part of that but I encourage people to get familiar with lambda expressions and learn to love them because they are extremely useful so today we were able to get a little funky we saw how we could use the built-in delegate type func of TT result rather than having our custom delegate type and we saw that func provides for a varying amount of parameters so we can have between 0 and 16 parameters and still use this built-in delegate type and since lambda expressions are simply anonymous delegates that means we can swap in lambda expressions wherever we're using func again when I see func declared somewhere in the code I treat that as a big flashing sign put your lambda expression here to get more information and to download the code samples feel free to head over to WWE my baits calm and we'll see you next time
Info
Channel: Jeremy Clark
Views: 15,999
Rating: undefined out of 5
Keywords: C# (Programming Language), C# Delegates, Anonymous Function
Id: 0nd-tcQcslc
Channel Id: undefined
Length: 18min 8sec (1088 seconds)
Published: Tue Dec 09 2014
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.