C# Events & Delegates

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Super exciting, I dont understand these concepts well enough and something about your style of teaching helps me to understand better.

👍︎︎ 4 👤︎︎ u/[deleted] 📅︎︎ Mar 18 2022 🗫︎ replies

Wow you explained this better than my CS professors did. Great stuff. Definitely worth the watch.

👍︎︎ 3 👤︎︎ u/CheezeyCheeze 📅︎︎ Mar 18 2022 🗫︎ replies

clash of clans font

👍︎︎ 2 👤︎︎ u/shygal_uwu 📅︎︎ Mar 18 2022 🗫︎ replies
Captions
hello boys and girls let's learn about events and delegates and we will start with delegates so simply put a delegate is just a variable which holds a method instead of data so to declare a delegate just use the a delegate keyword so what follows here is the signature of the function we would like to store so for now let's just uh sorry function with a return type of void and let's call it do something and let's say that it takes an argument of an inch so to simplify what a delegate definition is it's just the signature of a function it's not holding data it's not even holding the function it's just the uh setup of the function the guidelines if you will so it's comparable to a class definition okay it's not the actual class instance it's just the definition of the class if we want to use our delegate we need to now make an instance of this delegate type so let's do that let's say public and this will be of type do something and we'll call this something cool so now we have a variable of type do something and we can now assign to this just as if we would assign a variable of a class or an int right so let's make a constructor here and let's assign a function to something so let's make a new function here and we'll call this function one right and obviously it's going to be taking in the int and returning void just like our signature does here and here we will write to the console and we'll say uh function function one cold with value let's just fix that cool so now this uh variable actually holds a function we can now call it and put in something like one two three and if we press play here we'll see function one has been called with value one two three also sometimes you don't actually know if something has a value obviously we do here because we're assigning it right above it but you should check your delegates before calling them to see if they're null if they're not null then you can call it and uh null propagation makes this much nicer for us we can just uh do it like that with a question mark and an invoke it does the same thing cool so now we could actually assign this to another function and this one would be called function2 and we'll just copy that and just change that a little bit and we can call this one again and let's just say 456 and then play and there you go so as well as directly assigning a value to uh delegate we can also subscribe functions to the delegate so let's remove this and instead of directly assigning we can say plus equals function one and we can also subscribe it to plus equals function two and now when we call something and let's just say random number and press play we'll see now that both of them are called function 1 and function 2. and funnily enough i have just introduced you to the concept of events although technically we can't call it an event unless we use the event keyword here i'll go over what the event keyword is in a moment but uh events are just a way for classes to notify other classes and objects that something has happened or more specifically an event has occurred but before continuing let's step out of the dark ages for a moment uh because there are better ways to do this in our modern world i have not manually declared a delegate for many many years so there are modern single line alternatives to combine these two lines and the first one is event handler and let's just remove this stuff for now so the event handler is the standard way to trigger events in c so the event handler requires two parameters the first one being uh object of the sender so this is typically the uh object that is firing the event so we can just say this for example and then event args which is a way for you to pass custom data right now it's just a very simple object and i'll just say empty for now but you can expand event hugs to add whatever properties you want and that's an easy way for you to pass data through your events and although this is the most common way to set up your events it's not always what you need especially in game dev you usually don't need this extra information about the caller of the event so we have another even easier pre-made delegate and that is of type action so let's remove this so action is just a uh delegate with a return type of void and also uh no arguments and you use your action delegates in the same way that you use your manually created delegates so you can just do that and create a new method let's call this a simple function uh you can also directly assign it using uh an anonymous function like this and actually if you want you can assign a value directly in the declaration right it's saying that it's going to be ignored because we're doing that so if you want some uh to be able to pass extra data through you can use the generic version so right now uh we want something with an inch so we can now say something plus equals and we'll say the function one and we'll also say function two cool so that's a much easier way i'm sure you'll admit and if you need more data you can uh obviously add more data to the generic type um it can be classes it can be whatever and if you look they've actually manually assigned up to t16 so um it almost seems silly that it had to be this way but i suppose i suppose they thought about it and that's the best way to do it uh if you need a return type for your event which is a little bit weird i've never used a return type for event i think it seems a little bit clumsy but you can use the funk pre-made delegate the difference between an action and funk is that with an action uh the very last parameter here will just be a return type so everything before it will be the uh the the parameters for the function the last one will be the return type so this is just saying that the functions that you have assigned to this does not match the signature that you've declared so if we were to like change this to a string and just return anything it will now say function2 is is applicable it's it's it's good to go okay but that was enough theory let's actually put something into practice okay so we've got three classes on the right here we've got a guild we've got a member welcomer and then we've got a guild hole here where you can add a bedroom for the member so let's say we want to keep these three classes uh ignorant of of one another okay we want to keep them decoupled uh and we would like these two to action anytime a new member has been added so we can quite easily handle that uh using events so let's make a public event of type action and this will take in a string and this will be called new member added and in our add member function we will say new member added and we'll check it for null and we'll invoke it and we'll send in the member name so over in my main method here i've created instances of the three classes so now we can start hooking up our events so we could say guild new member added and let's assign that to the welcomer dot welcome member and then we'll say guild new member added and let's assign this one to the hall add bedroom so now if we press play we'll see a welcome tarot dev and a room has been added for me which is nice if you know that your event does not need to be tied to a specific instance that you've created of the class you can make it static which provides us a few luxuries so let's just remove these uh assignments here because it's static now we don't need a specific reference of the class so in our uh welcomer for example we can now say guild directly from the class whoops add new member and we'll say straight to welcome member this obviously breaks the decoupled nature but sometimes decoupling is not always a priority i find myself using static events far more than instance events a good example of a static event would be uh say you've got a whole bunch of enemies that derive from a base enemy class you could have a enemy killed event and your application doesn't necessarily care what enemy it is it's just that an enemy has died so your ui could uh pull into that event add to the kill count or you could subscribe to it from somewhere else and like play a little jingle or something this just allows you to subscribe to one event the actual class static event as opposed to subscribing to like every single enemy that's spawned but obviously it's contextual sometimes static's better sometimes it's not you just need to evaluate and decide which one to use so previously i said i would talk about the event keyword a bit more and you may be surprised but the event keyword actually does surprisingly little it doesn't add functionality it actually removes it so let's actually remove the event keyword here and i'll work backwards so down here in our other class our member welcomer instead of subscribing to this event let's actually directly assign to it in addition i will actually trigger this function uh externally from another class right so we're directly assigning to it and we're triggering from the member welcome in class now if we add the event keyword here we will find that we can now not assign to it we can still subscribe to it cannot assign to it and we now cannot uh actually fire it from an external class and that is all the event keyword does it just locks down external permissions a little bit so now you can obviously only call it from internally and if we wanted to we could also uh directly assign to it as well from in from internally here so that's all the event keyword does surprisingly so as you can see events are incredibly powerful in both enterprise and game development but on top of the standard c-sharp events unity actually have their own special events called unity events and if you've ever used a button on a canvas you've actually already been using unity events all along but let's head across and take a peek and i'll show you how to set up your own unity events so i've got this rather promiscuous little button here and when you touch it it makes the things on the right do a little dance which by the way i spent way too long making but it was really fun anyway this is done using the typical unity setup right so we've got our references here to our three different things uh on mouse down and by the way this is not actually a canvas button this is literally just a game object with a collider on it as you can see so on most down we're just calling the three functions on our objects but the problem with this is say tomorrow we want to add another three things right or we want to take one away or change one uh that requires coming back here changing the code it's not very designer friendly right in a team you ultimately want the programmer to design the systems and then you hand it off to the designer and the designer can just hook it all up and make a whole bunch of levels without you really doing anything to the code and also it's really just nice if you're just working as a solo developer too it's nice to just be able to make everything modular so let's actually change this and use unity events instead so we don't need those references anymore so they can f off and we'll create a unity event variable and this will be clicked and instead of all of those function calls we can literally just say click invoke and a good thing about unity events when you're serializing them in the inspector is you don't actually need to null check them right so if you think about creating a list which is serialized in the inspector you don't actually need to initialize that yourself dude it's always going to have a value same thing for events okay so not only is that a smaller amount of code you'll see here that this is now completely modular we can just add uh objects here and you'll see it works just the same tomorrow you could decide that you want another two more so your designer could slap two more here and it would be as simple as adding two more uh events here and bob's your uncle you've expanded your system without changing any code now there are just a few things i would like to note so i'm sure there are some experienced developers right now just screaming at their monitor that i haven't shown how to unsubscribe and why you should unsubscribe from events i've just got an extra little demo here to show you exactly that so when i press play all these balls start spawning and i can click them to destroy them and every time a new one spawns they all flash and grow a little bit so let's have a look at what the code is doing so here we've got the ball spawner and we're just spawning a few balls i do a whole bunch rather start but every single time a ball is spawned i've got this public static event here called ball spawned and i just invoke that so in the ball script i am subscribing to the event in the on enabled hook and i am unsubscribing using the minus equals in the on disabled hook now the reason we do this is say you spawn 100 balls and they all subscribe to this event and then 50 of them die on the next time a ball is spawned our ball spawner is still going to try and fire those 100 events and 50 of them are going to have a no reference exception not only that but this is how you create memory leaks you're just going to continue subscribing to this event and not clearing the reference to this event and uh yeah that's just that's memory is it growing a good rule of thumb is whenever you subscribe to an event you should also handle the unsubscribe uh as well and because we need to unsubscribe from this event that means we cannot use an anonymous declaration right we can't use an anonymous function to subscribe to an event because now we don't have a reference to this so there's no way for us to unsubscribe from it and no uh this does not work uh because they are completely different anonymous functions so whenever you're subscribing to an event and you need to unsubscribe from it uh use an actual named method uh there are times when you don't need to unsubscribe from an event for example if you know that ball is going to outlive ball spawner when both spawner is collected by the garbage collector obviously all the references to these events are wiped so you don't need to manually do it then but just be sure always know if if you're gonna outlast it or not and if not make sure you are unsubscribing from the event another thing to note is yes you get a more decoupled system when you are using events obviously this is still not fully decoupled as uh ball relies on ball spawner but in my previous example the guild example we were using like an orchestrator the main method to subscribe the events to one another so that's that's relatively decoupled but with decoupling comes reduced clarity so it is harder to know at a glance what is actually listening to these events without like diving deep into it so it makes passing the code slightly slower it also makes debugging quite a lot harder so don't just go decoupling all the things for the sake of decoupling right making your life harder do a couple things when you need them to be decoupled events in the end are just a way to cross boundary lines so a good example is if you're building some kind of desktop application you've got your view you've got your code behind you can decouple those things so that you can chop and change the view whenever you want and you don't actually have to change the code behind you're just triggering and listening to events it's also good in things like if you're making an external package like a third-party library for people to install you can allow them to hook into your livestock lifecycle events if your components are tightly coupled by design uh there's no real reason to use events so yeah always just look for the right tool for the job it's not always events but they are incredibly powerful ah that is it i think i just about covered everything i hope i didn't miss anything hello there so this is editor matt from the next day i did in fact miss something which is passing delegates around like their parameters for functions so we'll see here in my guild class here i've got a function called do some task and it takes an action as a parameter so we can do some asynchronous logic here and then finally we can uh trigger the callback so then over here we've got our guild object and we're saying do some task and we're sending in an anonymous function here which is what we're defining as this and in the end we just say callback received so if we press play callback received cool and of course this doesn't actually need to be an anonymous function you could quite simply do a function like this some function this will take an ins num and then here you can just uh put in this and that will work as well so yeah you can just pass around delegates like their standard variables that's it
Info
Channel: Tarodev
Views: 53,892
Rating: undefined out of 5
Keywords: c#, csharp, events, delegates, events and delegates, what are delegates, learn delegates, learn events, unityevents, events unity c# events, c# delegates, learn to code, events in unity, decouple code, c# events, c# event, unity event system, unity c#
Id: 6NRqwL3N5Go
Channel Id: undefined
Length: 17min 21sec (1041 seconds)
Published: Fri Mar 18 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.