JeremyBytes - Lambdas & LINQ in C# - Part 3: Declarative Programming with LINQ

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 discussion of lambda expressions and link in c-sharp previously we took a look at the syntax of lambda expressions and also saw a cool feature called captured variables and last time we took a look at the syntax of link methods so that we could figure out how to use them easily in our code this time we're going to be looking at declarative programming specifically we'll see how link can help us add declarative style into our existing code but first we need to look at the differences between imperative programming and declarative programming with imperative programming we're telling the computer how to do something we're taking full control of the process and we have to manage all of the pieces with declarative programming we're telling the computer what we want and we're letting it figure out the best way to accomplish that task now as an example let's look at animation now in the WinForms world when we wanted to do animation we pretty much had to do everything ourselves so we would set up a timer and each time the timer would tick we would tell our object to move three pixels then we would tell it to move again and we would tell it to move again and then once it got to its endpoint we would tell it to stop in this situation we're taking full control over how to do this animation and if we want to add cool effects like easing to the beginning or end of the animation now we're doing some really tricky math to try to figure that out now one thing I love about WPF is it has a very declarative nature and that includes the animation so in the WPF world if we want to animate an object what we say is start here and here and take two seconds to do it and you know what why don't you add some easing as well and then we let the computer figure out exactly what needs to be done this takes a load of responsibility off of us and it makes our code much easier to read what we'll see is we can use link to bring declarative style programming into our existing code so let's go back to our application and take a look at exactly that so here we are in Visual Studio and we're going to go back and look code that we built in part one of this series specifically the code to set the selected item after we update our list box let's run our application to get a reminder of the functionality so when I click the refresh button we have items that come in from our library then if I select an item like Dylan hunt we show that selection in the upper left corner of our screen and when i refresh the data we'll see the selection stays in place that's because even though we're completely replacing the items in our list box we've saved off a copy of the selected item and then we located after we reload our list box now since we're looking in the items of our list box this has the effect of working with filters as well so if we filter it and the selected item is still there then we see we maintain our selection however if we select a filter that does not include that item then the selection goes away so let's go to our code and remind ourselves how we put this together this is all happening in our refresh button underscore click method that we have here at the top of the method before we do anything else we save off a copy of the current selected item in the list box this gives us a value that we can compare against later on then we do the work inside the body of our lambda expression now the first thing we do is we repopulate our list box we do this by setting the itemssource property and you can see we are also filtering and sorting our results like we added last time after that we try to set the selected item so the first thing we do is we make sure that our selected person is not null if it is null that just means we didn't have a previous selection after that we for each through all of the items in our list box and we try to find an item that matches the first name and the last name of our saved off person if we do find that then we set the selected item property of the list box now this code works and it does exactly what we wanted to do in this case but there's a few things that I don't like about this particular code the main thing that I don't like about this is the thing that we're trying to do is buried two levels deep inside the for each and the if statement what we actually want to do is set the selected item of our list box but we have to drill all the way into this statement to find that the other thing about this block of code is I have to do some thinking to figure out how it will behave in different situations so for example what happens if it does not find a match well in this case the selected item would remain unchanged which means it would maintain whatever previous value it had now I have to think about it in this case since we completely replace the items in our list box selected item will be null and so it will maintain that value now what happens if it finds more than one item that matches now that's not hard to figure out but we do have to think about how this behaves in this case if there's more than one match it will actually select the last item that it finds because it keeps iterating through that for each loop now if we were to change our code a little bit and add a break now it would use the first item that it finds and is this code hard to figure out definitely not but we do have to stop and think about it a little bit now this is a classic example of imperative programming I'm telling the computer exactly how to find this item I say I want you to iterate through each item on the list box each time you come across an item I want you to compare the first name and the last name properties if they match then go ahead and set the selected item if not keep going to the next item in the list and it will just keep iterating and iterating and iterating until it gets to the end of our collection but what I'm going to do instead is use a link method to turn this into a more declarative statement we'll let the computer figure out all of the details of how to locate the item we'll just tell it what we want so first let's go to help and take a look at the methods that we're looking for and again the linked methods are located on the ienumerable interface in the extension methods now the method that I'm going to pull out is one that's called single or default so let's go ahead and locate that and we'll go ahead and select this signature right here now if we look at this signature it should look familiar it is very similar to the wear method that we looked at last so this is an extension method on ienumerable of t source and again we can replace t source in this case with the person class that we're dealing with so this operates on an ienumerable of person but notice the return value rather than returning an ienumerable this is returning a single item and in our case that item will be a person object now if we look at the predicate parameter this should look familiar this is exactly the same predicate that we had when we looked at the where statement so this is a func of t source bool which again in our case will be a func of person bool and that means we need to provide a method that takes a person as a parameter and returns a true false value now I'll talk about the full functionality of this method in just a bit for now let's go ahead and add it to our code so here's what the primary difference is going to be rather than for eating through the items in our list box we're going to run a link method against it what I really like about this is I get to put the thing that I really care about the selected item of our list box right up front so I actually say person list box dot selected item equals this tells me right away exactly what I'm trying to do I'm trying to set the selected item of the list box now we're going to be looking at the items property of the person list box now what we've been doing with our other collections is just saying dot and then locating single or default or whatever method we want to use but notice that single or default is not showing up in this collection that's because items is not a strongly typed collection this is an item collection object which does implement the ienumerable interface but it does not implement the ienumerable of T interface the strongly typed interface that we need in order for single or default to work now fortunately for us there is a link method that we can use let's go back to help and I'm going to take a look at the of type method so let's scroll up a bit and here's the method that we want of type T result now this method signature is a bit different from the ones that we've seen before it is an extension method which we can tell by the this keyword but instead of operating on ienumerable of t source like our other methods have this just operates on i enumerable so this will work on an enumeration that is not strongly typed and that's exactly what we have in this items collection in our list box now notice the return that we get back from this it's an ienumerable of T result so we're taking an enumerable that is not strongly typed and turning it into an ienumerable that is strongly typed and all we need to do to select that type is fill in the T result generic type parameter that we have now at first glance this looks like something that would be doing a cast on the items in our enumeration but that's not actually the case instead it's doing a filter on those items what that means is that if we come across an item that doesn't match our generic type it doesn't throw an exception it just does not include it in the result now in our case this is going to be pretty easy because all of our items are of the same type and they are all of type person so let's go ahead and add this method to our code so now we'll just say items dot of type and then this is well we'll put in our person and this is a method so we do need to include the parentheses and the result coming back from this is an ienumerable of person well that's exactly what we need for our single or default method so let's go ahead and say dot single or default and notice we do have intellisense coming up at this point and in here we need to put a lambda expression and there are two overloads for single or default one that doesn't take a parameter and one that does if you want to see the differences between these I actually do have an article on my website that talks about this and if you follow the links for this video you'll find a link to that article now in this case we are using the one with the predicate so again we need a func of person bool so a lambda expression that takes a person as a parameter and returns a true false value so we'll just use P for our person and we'll say goes to P dot last name equals selected person dot last name and P dot first-name equals selected person first name and the last thing we need to do is just add our semicolon at the end of our statement so now that we can see the code let's talk a little bit about how single or default works now single or default uses this predicate to try to find a matching item in the enumeration that we're looking at so again this is looking through the items in our list box now if it finds a matching item it's going to return that item and that's what we assign to the selected item property of our list box but what happens if it doesn't find any items well that's what the or default is if this cannot find any matches it will return the default value for that type so because person is a reference type it will return a null now if we were using a value type such as integer it would return the bitwise 0 for that which would be 0 in the case of an integer now there is another scenario what if this finds more than one item in our collection that matches while single is expecting to find only one item which means if it finds more than one it will throw an exception and that's actually the behavior that we want in this case we're expecting to find one item at the most in our collection now because I know the behavior of this method I know exactly what to expect our selected item will either be a matching item if we find just one it will be null if we find no matching items and if we happen to find more than one match it will throw an exception and if we run our application will see that this operates exactly the same way that it did before so if we select Dylan huns and refresh our data again we'll see it maintains that selection if we apply a filter where he is included then it does maintain that and if we include a filter where he's not included then we get null back because it doesn't find any matching items at all now what if this isn't the exact behavior that you want well single or default actually has some friends so let's go back to help and take a quick look at those so here's the singular default method that we selected and again if it finds zero items it returns null if it finds one item it returns that match and if it finds more than one it throws an exception now it does have a sibling method called single it's expecting to find one and only one item so in this case if it finds one item it will return it but if it finds zero items it will throw an exception and if it finds more than one item it will throw an exception now these methods do have a cousin which is known as first so let's take a look at that so here's the method first so how does first behave well it's expecting to find at least one item so if it finds one item it will return that if it finds more than one item it will return the first one that it comes to and if it finds zero items it will throw an exception now there's another method here first or default in this case we get no exceptions at all if it finds one item it returns that if it finds more than one item it returns the first one that it comes across and if it finds zero items it will return the default value for that type so we can see it's pretty easy to choose among these four methods to get the behavior that we want now if you want to get a little crazy there is also a last and last or default again there's a ton of really cool methods in the link extension methods take some time go through the list and just explore to see what's actually there so if we go back to our code now we have a more declarative style rather than doing a for each and an if statement we're using the single or default method and when we use the single or default method we're saying you know what I don't care how you figure this out all I know is I want you to give me one item or a null back depending on what you find and here's the condition that I would like you to use and because we understand the behavior of this method we know that if it happens to find more than one item it will throw an exception the thing that I really really like about this block of code is the thing that I want to do is right up front I want to set the selected item so now I don't have to drill in two levels in order to find out what I'm really trying to do here and if we compare this to our previous code we can really see that difference more clearly so rather than having to drill into the middle of the code block we look right at the front of this code so what we've seen today is the difference between imperative programming and declarative programming with imperative programming we're telling the computer how to do its job so in our case we were using a for each loop to iterate over items and we were using an if statement in order to find a particular item and then we were assigning that to the selected item but with declarative programming we tell the computer what we want and we let it figure out all of the details so rather than going through that iteration we just say you know what single or default give me one or give me null and you know what if you find more than one give me an exception and then we let the computer figure out how to actually locate those items now I'm a really big fan of the single and first methods that we looked at here's a chart that shows how the different methods behave so again if we call single if there's zero matches we get an exception if there's one match it returns that item and if there's more than one match it throws an exception for single or default if it finds no items it returns the default value and again that will be either null for reference types or bitwise zero for value types if it finds one match it returns that item and if it finds more than one it throws an exception and we can see for first if it finds no matches it throws an exception if it finds one item it gives us that item and if it finds more than one it returns us the first one that it comes to and with first or default we won't get any exceptions at all we'll either get the default value if it finds nothing or we'll get the first item that it comes to so today we saw how Linc can help us write declarative code code where we tell the computer what we want and then we let it figure out how to do it Linc is really awesome and in fact it lets us add a lot of functional style programming to our c-sharp code but talking about functional programming is definitely a topic for another day and this really brings us to the end of looking at the basics of lambda expression and link and c-sharp now I will have a couple bonus videos in this series one that we'll take a look at using captured variables with a for loop and one that will dive into the syntax of the join method that one's really fun because it actually has five parameters and three of those are delegates which means that we'll end up with three different lambda expressions in our code sounds scary but it's really not that hard once we break the pieces down so until then be sure to visit www.carmensognonvi.com/newsletter
Info
Channel: Jeremy Clark
Views: 11,695
Rating: undefined out of 5
Keywords: C# (Programming Language), Language Integrated Query (Programming Language), Declarative Programming (Programming Language Paradigm), Anonymous Function, Lambda Expressions
Id: QgRVmdJu5rs
Channel Id: undefined
Length: 18min 16sec (1096 seconds)
Published: Tue Apr 14 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.