C# Generics - Put anything in me baby

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Off from work and now, its time to do what i love the most! Watch Taro and learn new things!

👍︎︎ 2 👤︎︎ u/herkdes 📅︎︎ Nov 05 2021 🗫︎ replies

Nice one! bit generic though. badum tss

👍︎︎ 1 👤︎︎ u/Putrid-Ad7519 📅︎︎ Nov 19 2021 🗫︎ replies
Captions
hello welcome so in this video i'm going to be teaching you about generics if you don't know what generics are chances are you've probably used them in the past at some point for example uh if you've ever used a list before and as you can see this is in the system collections generic namespace you might have noticed these angle brackets and that is because list is a generic class it allows us to define the type that the collection is going to be so for this let's use string and let's uh just call this games and this is going to be equal to a new list of string so then down here we can say games dot add and as you can see it is giving us actual type safety here it is saying that it requires a type of uh string so if we just try to put in a number here uh it would say no that is incorrect we need a string so let's put in a game uh dark souls cool and then we could make another list down here where we would in fact use an int so uh my ins i don't really know what a cool int list would have been and down here we can say my ins dot add and then as you can see it's now giving us the type safety for an integer so we can say 69 excellent so to understand this a little bit deeper let's create our very first generic class so as you can see i've got just two files here program and declarations so this one's the program and this one's the declarations i just figured i'll keep them separate it will make it nice and neat so over here let's make a class and this will be called uh generic class and now this is where we put our angle brackets so here we're going to say that there needs to be a type of t now t is just an alias and it's convention in c sharp to make your first uh generic alias t just like its convention in your for loop to put i as the first iterator so and then you could go to like u and so on you can have as many generic types as you would like in this generic class so that's the only difference to make a generic class compared to a normal class just adding these angle brackets and putting the the alias of your of your data that you're going to put in so now let's actually store what this data is going to be so we can say public type of t and this will be data so now over here we can actually create this class this generic class that we've just made so let's say my class is equal to new generic class and as you can see now we can now put in our own type into this so let's call this a string cool so we have just made our own uh generic class in the same way that list creates theirs we've got our class name and then the generic type that it takes and if we just deconstruct this list class here we will see that they do exactly the same it is a list of type t right list is just a generic class that is provided by c sharp but they're using generics in the same way that we're using generics so that's cool and now here we've got our little field here of data we can say my class dot data is equal to and as we're using a string here it will say that data is of type string so we can put in wobbly cool this is a little bit messy so we could actually add a constructor here and in this constructor it will take a type of uh data and then we can just set our data is equal to data just like that so now instead of doing it like that we can just directly say right in here wobbly so now we have a generic class with a constructor that actually takes the type of t into it and of course if i change this to inch that would now say no this is a generic class of int and i need an uh an integer excellent now generics is not just limited to a class we can actually make a generic function so we could do void let's call this function print maybe and it's going to be of type t and then in here it's going to take type t and this will be the input and now let's uh console.writeline and this will take in input so now this function can take in any data type and then we can print it to the console so let's try that let's say print and this will be uh let's just put in an integer now if we press play here we'll say that it prints out 420 and we can reuse this function easily with even a string so this will be let's say a loop hero and then even further we could let's say we had a class here public class hero we could even do it with a new version of this hero we can use this same code for everything so let's try that there we go so obviously when there's a string or an inch there's special logic in those uh in those value types that behave differently when you print something out our hero doesn't so it's just going to print out the name now just imagine this was not just writing a line say say it's doing something a little bit more complex right uh you without generics you may have had to write a function for integers for uh strings and for hero and all your other classes and structs right but with generics you can now reuse that for all your different types okay excellent so let's actually uh remove this function and let's actually put it in this this function we don't actually need this we don't need this because we've already got the thing that we want to print we're just printing data oh yeah so we've got this generic class it's got this function inside of it now and now we can say here my class dot print and the output will be expected it will just say wobbly as that is we're using a string here as our generic type so being able to send anything into a generic class or function uh is great but it can also be limiting like it's actually too generic what if we have a uh in our hero class here we've got a public void attack function and let's also say that it's got a public uh inch damage and also a public string name right and then this attack function will just say console.writeline and it will say our name did damage damage okay so now we've got a hero here with a name and damage and there's a function on it and it just prints uh this hero did this damage okay so let's actually rename this generic class let's actually call this like uh hero helper or something like that okay so we're making a little bit less generic now so don't get confused this is uh not the actual hero right our hero class is here this is a hero helper we're we're putting our hero into this as the generic function so let's just move this just so we've got a little bit of extra room here so let's say from this hero helper i would like to force my hero to attack so we could have a function here called force hero to attack and what we want to do is we want to make this data which is going to be the hero right uh call this function attack on this hero class because we've sent in hiro as the generic type but there's a problem as this is so generic right it doesn't know what it is this this t as far as the compiler knows is an inch right it could be a a dictionary a key value pair it could be a list it could be anything in the world which means it doesn't know what uh values and methods are actually on this thing so as i said being able to send in something anything is good but it's also a constraint so we need access uh to this hero right so and also just to iterate this fact a little bit more let's say we've got uh a mage class right and that that inherits hero and let's say we've got a warrior class and let's say we've got uh an archer and a million others right say we've got a million other classes all inheriting from hero and then let's delete some of this stuff i'm going to create my hero up here so var warrior equals new warrior so now i've got my warrior and also i'm going to set its name to tarot dev and it's damage to 420 powerful okay so we've got oh that should be a lowercase cool and now i'm going to make uh my hero helper so i'm going to call this helper equals new hero helper and i'm going to say this is going to be of type warrior and it is taking in my warrior so we're using this in the same way that we used our previous generic class we we're giving it the type that we want it to be and then we're actually giving it the value and now obviously we can still say helper dot print and this will print and i'll just demonstrate that it'll print the name of the class warrior cool but i want it to do more than that right this is a hero helper i want it to i want to be able to force my hero to attack so as i said previously it's great being able to put in anything to this generic class but sometimes it's a limitation so this is where constraints come into it generic constraints so we can say uh hero helper take some type of t where t equals a type where we're saying we're confining this generic method to have to use a specific type this one will be of type hero okay so now it doesn't matter if it is a warrior a archer a mage or even just the hero itself uh which we shouldn't let let's let's make that abstract that's beside the point of the tutorial but obviously you wouldn't allow uh your base class to be initiated as an actual hero so this function is just saying as long as t is of type hero i'm good to go and the benefit that this gives us is now we have access to the hero methods here so now we can say attack and before it didn't know that it was a hero so we didn't have access to that function and now on the flip side as this is requiring a hero we now cannot use an interior right we can't use an in here because this is not of type hero so this allows us to be more flexible with what we do with our generic methods and functions okay so now something a little bit more advanced let's make a factory method which will actually generate create these heroes for us all from just one function so let's say this is going to return type of t and this will be our hero factory and this will be a generic function so type of t and in here let's actually take a parameter that we would like the hero uh to be called and this will be where t is of type hero let's give ourselves a little bit of room here and close the brackets now in here we actually need to create this t right we still don't know what it is but we need to actually generate the t so let's say t new hero is equal to t whoops nu t parentheses now this is giving us an error uh and that is because although we know that it is type of type t we don't know if these classes that this uh t here is going to be we don't know how it is constructed right this mage here could have a constructor which takes in uh inch for its damage right whereas the warrior might not and then the archer might have a constructor that takes five arguments so we don't know the see the compiler won't know for sure so it could actually throw a runtime error right now we can fix this by adding an additional constraint to our generic method and that is to say to tell the compiler that whatever we send into this function it will have a constructor with no parameters okay we are saying that this function will only accept uh types where the the class has no uh parameters in its constructor so now that we've uh gotten rid of our squiggly here we can actually return new hero whoops new hero and there is our generic function so let's try this out let's say var uh archer equals hero factory and let's send in archer right and then it's asking for our hero name ah and i didn't actually fill that out so as we know that this is of type hero here we can say new hero and it has a name and we can say hero name what's in the archer's name i don't want to do legal asses like everybody does that but uh the show must go on legolas and i bet you i spelt that room legalize whatevs sorry uh so this works because archer has uh well no constructor but also that it's got no parameters in the constructor if we wanted to change this to mage it's going to say no you are you have told us that the object that you're trying to construct has a constructor with zero parameters all right so we can actually now in a generic function generate objects as long as the type that we send in has a parameter less constructor cool so as you can see generics can be super powerful they can make your code dry af by allowing you to reuse code snippets and really you've almost learned everything there is to know about generics like i do want to show you one more thing so we've got our heroes here cool but let's say we've also got uh i don't know uh a chair right we've got a chair and we've got a uh manager all right so this could be a furniture store uh it could be a game too because heroes need chairs uh and a manager of an in or something i don't know and these are all super unrelated objects and none of them can really derive from one another right like i'm not going to make a chair implement hero because that would be stupid uh but if someone makes a game of that you're gonna give me credit at least all right so i'm just trying to think of a scenario uh say you're say you're making an mmo right and let's actually change this to uh the the anvil so say you're making an mmo and uh you're you've got a mini map and let's actually change this to be more relevant let's call this a mailbox right let's say all these things have a shared uh job and that is to ping your map okay we obviously can't uh derive anvil from hero okay that wouldn't make sense so let's make a public interface and this will be of iping and then this just has a required function called ping map like that okay so then our mailbox will implement i ping and it will have that function there and i'm not going to actually implement it but let's just assume that that one that map shows a map icon on the minimap right and then anvil will do the same and hero will do the same let's just assume that like it shows the class icon on there this could possibly be overridden or something on these derived classes so now these seemingly completely random objects we can now write a function that can action any of them so this will be of type this will return type void and this will be ping map and this will take in a type of t and this will type the actual data will be t so let's just say input object and our constraint here will be where t is i ping and now we can call input object.pingmap so now an anvil a mailbox and a archer warrior mage like any type of hero can we can now reuse uh one function to perform different logic on all of them right and they're all actually doing different things they're showing different icons like if it's a hero it could show up in red or it could show up on uh green if you're in a party or something you know so that's how you can mix generics with interfaces to create like true code reusability so there it is uh that's generics i hope my use cases were nice and easy to understand i probably should have gone over this one in my head a little bit more pre-planned it but i think it turned out alright if you learned something or if you enjoyed the video subscribe let me know in the comments if you enjoyed it and uh if there's a topic that you would like me to cover maybe you're having trouble with something also if you're feeling lonely come over into my discord have a chat we'll talk the uh let me know about the game that you're making or something and yeah i think that's it so i'll see you in the next video ciao
Info
Channel: Tarodev
Views: 7,356
Rating: undefined out of 5
Keywords: tarodev, tutorial, c#, generics, c# generics, #c dry, c sharp, csharp, c# fundamentals, c# basics, csharp basics, c# tutorial, c# generic methods, generics in c#, unity, learn c#, c# programming, game development, game development unity
Id: YEHbjy3JBtE
Channel Id: undefined
Length: 18min 43sec (1123 seconds)
Published: Fri Nov 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.