Advanced C#: Lesson 5 - Generics

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome to the fifth lesson on advanced c-sharp programming today we re talking about generics we're going to talk about what generics are why we use generics and how we use generics so I personally think that learning generics is the easiest by actually seeing it in examples but I I still want to give a basic definition of what generics are or maybe not exactly what generics are but why we use them because once you could understand why we would want to use generics it just makes sense so essentially generics allow us to not have to hard code data types into whatever we're designing so if we're designing a class instead of having to hard code certain members in it let's say we have an integer remember we can use generics to tell when when we're running the code we can tell the class what we want that class to be using so instead of using an int we could say use a double instead when we're writing the code so instead of having a hard code that that data value in we can tell it while we're actually writing the code so that uses the class now you may be saying why is that useful and there's a couple of reasons um you know let's say we're building a class that does multiple things and this is really a good way to look at this is when we're building collection types so let's say we're building out some kind of wrapper class around a basic list so this this we're just going to make a class that holds things in an array I guess that's the easiest way to do it now if we're writing the code for this let's say we wanted it to hold integers we would behind the scenes in this class we'd make an integer array that will hold our values which is okay but then what happens when someone wants to start storing doubles in it as well what do we do then you know we would have to build a whole new wrapper class and make this whole new collection that will be a double array now that that's the reason why we have Genet and this is the reason why or use the problems that we want to fix we don't want to have to make multiple classes to so that we can use multiple types so like I said if we have two collections let's say we have my int list and my double list we have to create those two separate ones if we want to store integers or if you want to store doubles let's say then we wanna make another one well if we want to store strings you know how are we going to do this what do you want to store an array of strings well to make a whole new class a whole new collection that will store strings like I said this is what generics fix by using generics when we're creating an instance of the class we can say oh I want this one to be a string array or I want this one to be a double array that's the benefits of using generics and I'm going to show you what I mean by this by doing this example of a basic lists so let's start off with building this integer array class wrapper that's what I want to start out with and so that we can see the problem and and see how we can fix it with generics so the first thing I'm going to do is I'm going to create a new class and my new class I'm going to call it I don't know my int list my int list I'm creating a new custom list and I called it my int list now this is going to be a really basic class all I want is behind the scenes I'm gonna have a private integer um yeah I guess I could do an integer array I could use a list also but I don't want to get into generics yet so I'm just going to use an array so I'm going to say private int and this is going to be my int array behind the scenes in my constructor of my int list I'm just going to give this some memory so int array equals new int array I want to say it has 5 slots this is just a little hard coding behind the scenes so there's my behind the scenes collection so I'm building this wrapper around this array so that I can call I want to make two functions actually I'm just going to do Janna make two functions the first one's going to be an adding function that you can add a value to this collection so public void add int the value that I want to add into this okay so I need one more thing before I can actually do this I'm going to create another private member and this is going to be my count and my count is going to be how many elements I have in this so that my add function knows what to do so now I'm going to do it my add function I'm going to go int array sub count equals value and then count plus plus so that will set me up for the next one I also want to put in a check to make sure I don't go out of bounds this is just like a little extra things so if count is greater than great greater than or equal to five um then I'm just going to return I guess I can just do it that way so by putting this check in now my add function is safe so this is let me go over this one more time I have my behind-the-scenes array and this is going to hold my integer values that are passed and my add function calls it make sure that we're inside the bounds of the array and if we are then we'll just access the account slot dump the value in that or whatever it's passed in and make count plus plus go up by one so next time someone calls an add function they'll have somewhere to add it um okay so but then the last thing I want to do is I'm just going to create a a show function so public void show that will just show all the elements of the write and prints it out so I'm going to say for n I 0 as long as I is less than 5 I plus plus and I'm gonna go to console dot write line um int array sub I and that that's it so this is my basic wrapper class I created this little basic class with an array in the behind the scenes and all the user has to worry about is calling adder or show and they can add things to this right and show it I didn't make a remove function because I don't want to get into data structures too much so I'm just trying to emphasize this point of generics so let's go ahead and just test out this um data collection data structure so I'm gonna go my int list list equals new my int list I'm gonna go list dot add 5 5 55 and 68 I'm going to add those three and then I'm going to go a list dot show and let's go ahead and run it and as you can see everything is working fine I added 555 since 68 now the reason why I'm getting these two extra zeros you because inside my for loop I'm going up to 5 I could change this just the count but I don't want to confuse anyone so now if I go up to count now if I run it now we'll just see the values that are just stored into the array so we have that 555 and 68 now this video is not about data structures it's this is not about building this class it's more about the reason why generics are important so as you can see this works now this is this is the problem I have this list that that you could add things to and then you can show in and you can see the values that are stored into it this is what I have the problem arises when I try to add a value that I can't use like 55.5 what happens here this is the problem I'm getting an error because it's an behind the scenes I'm storing it into an integer array and my add function requires an int to be passed in that is the problem so if I wanted to now make a collection type that can store doubles which like this 85.5 I have to recreate this entire thing that utilized a double instead same thing if I wanted to add maybe a string like hello I want to add this I'll have to recreate this class that does it because as you can see I called it my int array because I knew I wasn't going to use generics and this is only designed for an integer so this hopefully you can see why we want to use generics so now let's now we see the problem and why generics are important let's go ahead and implement generics to fix this problem so let's go ahead and I'm going to leave that 55.5 and I'll make this 56 okay let's go ahead and implement generics now so inside of our class this is just syntax it next to our class definition now if you're coming from C++ this is slightly different than templates I mean the syntax at least so inside of this I'm going to use generic syntax and these are the angle brackets are left and I mean greater than and less than science so inside of this I'm going to specify and identify I'm going to say T in this case and I'm going to put this T next to my class and what this is signifying is that this T can be used anywhere inside this class as a data type and this data type is resolves to whatever is passed in when they're creating the class so now that I have this T I could put this T anywhere I see an integer so let's go ahead here I see there in my ad function I see it um actually I don't this mr. stay as an integer sorry about that the count is always going to be an integer and that doesn't need to get changed to a T where else do we see in that's fine it's fine fine okay that's it so I only changed was my array behind the scenes is now based off of T its data type is now T and my add function takes in a parameter of tea so what we did was now when the user goes ahead and and creates an instance of his class he'll specify what type he wants to use and then that type will be replaced throughout here where the tea's are thus allowing us to create an array of any type rather than it having to be a integer so if we switch back to here we'll see we're getting errors and we need to specify our type so the first one I'm going to do is I'm going to say a double there double here in the angle brackets and now that I did that now my class is set up for generics so now as you can see the add for this 55.5 went away and when I run it now everything works because I'm saying that this is an array of double now if I were to actually now let's go ahead and look at the intelligence for the add function and as you can see the intelligence says that it looking for a double value even though behind the scenes it's a T it says double because we passed in double there if I go ahead and change this back to an integer watch what happens if we're gonna get that error again right here because the add function is now looking for an integer rather than a double I could change it to a string and now all good errors but I can fix that by just putting everything in between quotes to make them string values and by doing that now if I run it everything will be working again so this is the first part of generics that we're going to go over this is the part where we're marking our class as generic the entire class is a generic class and then we pass in the parameters that are necessary um now I'm not going this too much but I'm recent let you guys know you can have multiple generic parameters so I could have T and Y hypothetically separated by commas and now Y is another generic parameter that the user will have to add in he here so like int string and an int if I wanted to do that okay so there's another aspect of generics that I want to touch into really quickly um how we have a set up right now our generic parameters can be any value that the user passed in now that could be a good thing or a bad thing you know for our generic collection like that like this it's free it's probably a good thing but sometimes we're using generics that will not be a good thing and the reason is is because that it can be anything and because it can be anything it's very hard for us to do specific things to with it inside of our code and what I mean by that is um like if I had a generic parameter and I passed in a let's say a class called employee as the parameter I couldn't manipulate that employee really because I don't know what type it is um when they're passing in it's a generic parameter inside this class so I couldn't really manipulate and call functions on it that easily so this idea introduces us to a concept called constraints and constraints allow us to specify or um make the parameters that are passed into the generic arguments more um more restrictive meaning that you can say oh the parameters that are passed in must derive from this class or they must implement this interface or they must be a class or they must be a value type or things like this you can specify these things by using these this concept called constraints so let's go ahead and do an example of a basic constraint scenario let's go ahead and build a little class hierarchy so I'm going to go ahead and create a new class and my base class I'm going to have is going to be in animal ok my animal I mean we can just give it um some property's an animal has a name let's say all animals have a name so public string name so all I almost have a name and will also say that all animals have an age and that's it that's my animal my next class I'm going to build and I'll keep it in the same file I'm going to build a dog because a dog is a type of animal so my dog is going to derive from animal and then on top of that my dog I'm gonna say that a dog has maybe an owner and I guess a dog can also maybe have maybe will do type so like what type of dog so how this is working with a base class called animal which has a name and an age and a dog which has more specific characteristics because it's more specific type of animal as an owner and a type but a dog also has a name in an age because it derives from animal so that's my setup now inside of my generic class I want to be allowing this class to be storing um animals into this array um how is set up right now it would still work perfectly fine my show functions can be a little messed up that's why I'm just going to UM let's I I'm just going to comment that out right now kind of want to deal with that in confusing people I just want to deal with adding so how do I have it set up right now I can create some animals so let's go animal a1 equals new animal am going to say a1 age equals 5 a 1 dot name equals Bob I don't know and let's just create one more animal a - a - a - and he's 15 and his name is Fred whatever it does not matter so I have 2 animals so now using the the basic generic setup I can still do this I can still go in and say what should we call it animal so we're going to say animal and animal so now by doing this our generic class right here will be able to take in animals into the array but there's more to this now we need to start talking about constraints and we'll get into that here in a second okay so now that I have my generic class set up with animal I could if I want to go list on add and as you can see it's asking for an animal as a parameter so I'll add a one and then I'll add a two as well so I can do that so I can't add these things to my list now also one more thing because it's an animal it's saying that it's a list of animal I could create a dog D equals new dog d dot age equals to D dot name equals oops to no one do do that name equals I don't know Tim d dot owner equals frank d dot type equals who poop pool yeah okay so now I have an ID all set up I can also list that add arm D and add my dog to this collection because a dog is an animal so that's the basic setup so now that I have this now let's talk about the problem that can arise by doing this so I know that it's going to be an animal right which could be an animal or a dog as I told it it's going to be an animal but inside of my list um it's a generic parameter so I don't know what type will be so like let's say in my add function I wanted to display its name of the animal when it's added into the collection I couldn't do that right now because value dot and I don't know what it is I don't know it could be anything oh I know that this type derives from object that's why I see these things but I couldn't actually get its name right now now if I really want to get its name I could I could get the name of the animal what it's going to edit in if I did some manipulation so like watch this console dot write line let's go value as an animal so I'm saying treat the value as an animal and then get his name now this will work but even though it now it displays the animals names there's a problem and the problem is what if it isn't an animal what if I the programmer made another list of type int then it would be problems we have to do checking and blah blah blah it would just get ugly so that that's the problem um I mean I could actually demonstrate this if I went let's just comment this out really quickly and let's say this is an integer so let's say someone else wanted to use an integer and they did list dot add five and they ran that now you can see now the program crashes and we get an exception and because when it does this conversion right here it's becoming no but I'm not going to get into that but that's the problem because it this because anything can be passed into here I can't just say oh this is probably an animal that does not work we have to actually limit it somehow and limit the user's ability to pass in anything that they want and that's where like I said before constraints come in so how do we use a constraint okay let's put this back the constraint I'm going to use is let's go ahead and take this away I'm going to say in my class declaration I'm going to say where T : and then I'm going to say where T is in animal so by adding this little syntax next to my class I'm specifying a constraint I'm saying that the T can be anything that derives from animal or is an animal so that could be an animal or a dog and because of that now I am safe I'm safe so then here if I want to display the name not gonna just go console dot write line value dots and as you can see an agent name appear I don't even have to use that as keyword to convert it because it has to be an animal but because it is constraint so now if I do that now it works no problem now if we go back to the problem where what oh what if they use integers instead well let's see what happens if I go int int look what happens we're getting errors and the reason why we're getting these errors is because we put our constraints and we're pretty much saying that they there's a constraint it has to be an animal and it's are not animal I could do a dog however because a dog is an animal so the this though works in the constraints um so yeah this all works fine so let's go ahead and undo this so let me just quickly sum up this one more time constraints allow us to restrict um access to or restrict what the generic parameter of your class can be or our method which we'll get to um so these constraints now you may be saying okay why do we want that and the reason is if we want to be able to interact with these objects and interact with these things inside of our class we can use constraints to help ensure that what we're actually talking about is it so if we add a constraint of an animal we can be sure that that when we start using that generic parameter that it is an animal and if we know it is an animal then we're good to go now there are many other reasons why you may want to use constraints and you'll be when you're using generics you'll just run into them like oh oh this is a good use for a constraint and another cool thing is you can add multiple constraints so that's what makes it more powerful than maybe just making it the the array of type animal you could use multiple constraints so you can say you know um if it's if it's an animal if it's this if it implements this so you can do all those kinds of thing with multiple constraints so let's go ahead and let's talk a little bit about generic methods now and to what you need to know about generic methods are is that they're the same exact thing as generic classes except that they are on the function instead so let's go ahead and I'm just going to interact I'm going to forget this list right now I'm going to interact with our animal class and I'm going to create a function on our animal class that just nah let's go on the dog class that the function will just be public void bark and whatever or may speak is better speak and whatever you pass into its parameters it will speak whatever it is so we can use generic parameters because let's say if I did int value right here then our dog could only speak an integer hypothetically let's go ahead and test this out so are there animal a one dots I don't know it's a dog hold on I forgot it's not an animal it's a dog so let's go ahead and get our dog so if I wanted to do that speak I need an integer value and if I run that we get the sub five if I try to do maybe hello we get an error so that's the X or maybe a reason why we want to use a generic parameter on a a generic function so inside of our animal class I'm going to convert this into generics so the syntax is the same on to put in my little thing there put my T there and then we're good to go so now instead though when we call the function I'm going to specify the generic here so I'm going to say string and then now hello will war let's go ahead and run this hello will work now I'm saying I'm I'm passing in this ring so by doing that if I highlight to speak now it says it's looking for a string value instead if I made it an integer then it's looking for an integer value so I put five in that works now if I'm looking for a double I can put double in and then I can put 5.5 and that works what else okay or is that single that works fine so by doing a generic function it allows us to do the same things of generic class we can specify what types our function should be and there are lots of benefits of doing this you know I can't name them all but there's just reasons why you know and this is maybe the one good example that your speak function can speak any type of data hypothetically now once again the problem will arise where we need constraints and the same thing applies with with functions I can add constraints to this so I can say where T is I don't know a dog or something so I can add constraints as well and this constraint right here should make this error as you can see it does but if I the dog but then I don't have a dog okay anyway I could do D probably okay but anyway why my point is that you can add constraints to functions as well that allow you to help restrict absolutely that's really all constraints do they help you restrict what can be passed into these generic parameters because by default a generic parameter can be any data type that you want so constraints allow us to help specify and also you can have multiple generic parameters like I said as well doesn't have to just be one alright so that's going to be it for this lesson we talked about what generics were why we use them we looked at classes with them generic classes talked about constraints a little bit and then we talked about generic functions right now so I'm just going to leave you off with this is the base this is an introduction to generics like I always say if you want more details and more about generics this is write a comment and we can go into it more into the more the advanced things but like I said in the beginning of the video once you understand why we want you generics it comes really easily and I just want to add that um generics can be used with lots of things generics can be used with strokes generics to be used with interface Internet can be used with delegates generics can be used with a lots of things so once you understand with this you can apply generics to delegates you couldn't apply generics to interfaces and you comply generics wherever you most likely really want so that's it for this video um I hope everyone enjoyed it and be sure to stay tuned for any upcoming new videos thanks for watching
Info
Channel: Jesse Dietrichson
Views: 37,635
Rating: undefined out of 5
Keywords: C# (Programming Language), Generic Programming (Programming Language Paradigm), Advanced, Training, Tutorial, Generics, c#, Constraints
Id: U4E5j45swiI
Channel Id: undefined
Length: 29min 47sec (1787 seconds)
Published: Tue Dec 31 2013
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.