C# Generics Tutorial: Whats and Whys | Mosh

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys my name is mohammad ani and in this video I'm going to talk about c-sharp generics before we start with generics let me explain what problem generics came to solve in Dolphin version 1 we didn't have generics so let's say we wanted to create a list to store a list of numbers this is a simple and basic implementation of a list we could have a method called add to add a number to the list and an indexer that returns their number at the given index now of course there are more methods like remove and find and I'm just leaving that for simplicity here because the intention is to talk about generics and not data structures now if you wanted to store books in a list obviously this class wouldn't work so we had to go and create a class like this call it book list with a method called add a parameter called book and similar indexer now the problem here is for every type we have to create a separate list and this is a lot of code duplication and not productive plus if there is a bug we have to fix it in multiple places so one solution to fix this is to use a list of objects something like this with the object because the parent class for every type in dotnet we can easily pass any types to this method here or get any object from this indexer but there is another problem here the problem is performance if we use this class for storing value types like integers every time we insert a value type inside this list it has to be boxed to be stored as an object and every time we access that value it has to be unboxed and this has a performance penalty or even if you use reference types every time we want to cast an object let's say a book to an object or vice versa it's casting again has performance penalty so generics came as a solution to resolve this problem with generics we create a class once and reuse it multiple times and it doesn't have the performance penalty like with the object list here so let's see how we can create a generic list let me get rid of this code here so I'm going to create my generic list next to this one so you can see the differences let's start with public class I call it generic list now generics have a parameter and the parameters are specified with angle brackets so like this and we usually call them T as in short for template or type now we create our head method now instead of getting a book here you would get a T what is T we don't know yet the consumer of this class will specify that I will show you in a second similarly to get the object at the given index we return T that's all we have to do now let's see how we can use that we go to our program CSS so here your instant sharing a book object your is tensioning a list of numbers as you see and we're instantiating a list of books note that the problem here is that we have two different types of lists we can simply use our generic list instead of these two classes here so I can actually comment out this piece of code now let's create a list of numbers I use the generic list and here I specify the type of tea that we specified earlier so in this case we want the list of integers so I put it in here and now when I access the add method note that the parameter is of type integer we can use the same generic list to store a list of books so I specify book as the template parameter and say books that had now the add method gets an object of type book so new book blah blah blah so see we get code reusability and we don't have that performance penalty why and runtime our generic list is actually a list of books it's not a list of objects so there is no casting or boxing so this is the basics of creating a generic list now in practical terms most often you will be using generics as opposed to creating ones in fact I personally in my professional career as a.net developer have very rarely come across situations that I had to create generic classes or generic methods I would say maybe three or four times over the course of a few years most often you will be using the generic lists that are actually part of dotnet so you're not going to create a generic list in fact let me show you where all the generic collections are in dotnet so you go to system that collections generic and look here we've got a bunch of classes like dictionary at some interfaces like a collection I dictionary I in your Mirabal which is pretty popular i list links list list which is like our generic list queue sorted list stack and so on but in case you need to create a generic for the application you're working on the rest of this video I'm going to cover more details about creating generics so let's get back to our generic here see here T is a parameter we could have multiple parameters for example a use case of that is for dictionaries a dictionary is a data structure that uses a hash table to store and retrieve objects which provides a very fast and efficient way to access objects so with a dictionary we need to specify a key and a value and they can be of any type so let me create a dictionary here public class generic dictionary so I want a key here and a value note that I'm prefixing them with T and giving a proper name here like this is the template parameter for key and this is the template parameter for value I have seen some developers use something like T U or V here which actually makes no sense in terms of code readability so always prefix your generic parameters with T and then give it a proper name so in this case our dictionary has two parameters T key and T value our add method would look something like this T key key T value value now to use that we can go back to our program CS let me create a genera here generic dictionary I want my keys to be off type say string and values can be of type book this way I can call the add method and note that the first parameter is a string and the second is a book so I can say 1 2 3 4 and I'm going to store this book here just like that another thing in a tuna generics is constraints look in this case our generic list here or generic dictionary any type can be passed here there is no limitation sometimes this is good like in terms of list we probably want to store a list of anything and everything so there is no need to apply constraint but sometimes you would want to limit what is being sent here let me walk you through some examples so back to our programs yes here and we use resharper to put it in a separate file okay let's say we would like to create a method that gets two parameters let's say two numbers and returns the bigger one so typically this is how we do it so if a is bigger than B we return a otherwise we return P now if you want to create a generic version of that this is how we do it so public instead of returning int return T and the name of the method here we add the template parameter and of course both of our parameters are going to be of type T so T a and T P now see if I write the exact same code it's not going to work why because at this time the compiler doesn't know the type of T so it cannot apply comparison between a and B at this point it thinks a and B are both objects let me show you that so these are the methods that are available in a which come from the object class so what we need to do here is we want to assume that both a and B implement the I comparable interface which provides a method call compare to and with that we can compare these two objects so that's a use case where we need to apply a constraint we apply a constraint by going here at the end of the method and saying where tea use : as in is I comparable with that if I say a dot see we get a new method here compared to which comes from my comparable so with that we can say if a compare to B is greater than zero return a otherwise return B also note that here I created a generic method inside a non-generic class and that's perfectly fine so you don't always have to start with the generic class you could potentially move this template here to the class level so utilities for T where T is I comparable and then we don't have to repeat that here and we can just get rid of that just like that okay now that you have an understanding of constraints and why we need them let me show you the other types of constraints here are five types of constraints you can say where T is I comparable as in applying a constraint to an interface or you can apply constraint to a class this case we are saying if T is a product or any of its children any of its subclasses you can say T should be a value type so we use the keyword struct or you could say where T is a class as in it has to be a reference type or you can say where T is an object that has a default constructor now don't worry I'm going to walk you through these with examples so so far you have seen a constraint to an interface let's take a look at a constraint to a class so I create class here public class a discount calculator T product where T products is a product now I'm going to move this to a separate file so in that case I can create a method here let's call it calculate discount which gets a parameter of type product or any of its subclasses and here look we get the price and title attribute or property earlier I created this product class let me show you so this is my product class we have a title and a price we also have a book class here that derives from the product and adds an extra property here called ispn so with that constraint when we say t product should be a product or any of its subclasses we have access to all of its properties or methods here now we don't really care about the actual calculation of the discount but you got the point let's see an example of a constraint to a value type so a public class nullable t where t is a value type let me move that to a separate file okay what is this use for well in c-sharp as you know value types cannot be null so an integer should have a value like 0 1 2 3 it cannot be not we can use this class to give our value types the ability to be nullable so let's create a constructor here let's say tractor we can get we can get a value and in this class I'm going to store it as an object because I want it to be novel so private object value and here let me initialize it with resharper we can press alt and enter here and enter and it automatically initializes my private field with the value passed in the constructor now I want this class to have a property called has value so if my object has a value it returns true otherwise if it's null it returns false get return so if value is not now return true and we can have a method called public which returns t get value or default so with this method if our object has initialized let's say we have a number that is set to 5 it returns the value which is 5 otherwise it returns the default value or that type so for integers it's 0 so what we need to do is we say if it has value then return value we just have to cast it because this value here is of type object right but this cast is perfectly fine and it's safe because that's what we are passing here in the constructor we're storing it here and it's basically being boxed to be stored in the object but here we are unboxing it and that's perfectly fine now what if it's not set what if it's not we need to find the default value for that type how do we do that we use the default operator so we say return default of T so default is a good keyword that you need to know now with this class what we can do is we can go ahead and actually I forgot to create a default constructor here in case the value is not set now let's go to our program CS and use that I'm going to clear everything here we don't need them anymore so I can say for number equals new nullable of int I can give it a value like five let's look something to consult so CW it's a code snippet press tab out a has value plus number that has value console.writeline and the actual value is plus number that get value or default let's run this code so note that yes it has a value and its value is set to five now we can use this class without setting a value in this case we have an honorable integer so let's run this again so it has a value no what is the default value it's zero now you don't really have to go and create this nullable class is actually part of dotnet framework you can find it in system dot nullable is defined here and in fact it's a structure and look at this icon here it's not a class so let's go here so this not able is using a straight to specify the T has to be a value type let's look at another example let's go to our utilities class here let me create another metal here public void do something with T now let's say in some specific scenarios we want to instantiate and instance of T so if you want to create an object you want to do something like that but that doesn't work because at this time the compiler doesn't know exactly what type T is referring to all it knows is that T should implement a comparable interface if you want to instantiate T here you need a default constructor right so what you can do is to apply a second constraint here you can separate constraints food coma so to have a constraint to a default constructor that's what you use new now this is perfectly fine so with constant and specify that T must implement a given interface or B of a given type or any of its subclasses or be a value type or a reference type or have a default constructor I hope you enjoyed this video and thank you for watching
Info
Channel: Programming with Mosh
Views: 201,719
Rating: undefined out of 5
Keywords: c#, csharp, generics, .net, dotnet, C# (Programming Language), code with mosh, programming with mosh, c# generic methods, c# generics
Id: gyal6TbgmSU
Channel Id: undefined
Length: 19min 57sec (1197 seconds)
Published: Fri May 01 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.