What are Closures in C# and why you NEED to know about them

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody i'm nick and today i'm going to try and explain what is a closure in c-sharp and how it's wasting your memory now with anything related to performance whether that's speed or memory please understand that it's not a problem until you need to deal with it so anything that i'm going to show you today shouldn't be something that you should just go away and try and fix because memory might not be and most likely isn't the problem in your applications we have a lot of ram we have huge servers we usually don't need to worry about them but if you need to optimize for memory closures is something that you can actually very relatively easily deal with and in this way i'm going to try and explain what they are i'm not going to use very technical terms or maybe the 100 accurate terms and i'm going to do that because i think that using terms like lexical scope or free variables can actually be weird for developers trying to understand the concept so i'm going to use my own plain english to explain to you what are closest in c sharp but you don't need to go out of this video and optimize all your applications by removing closures this is only a problem when it becomes one and by default it's not so with that out of the way let's go straight into the code if you like this out of content and you want to see more make sure you subscribe with the notification bell to get uploaded when i upload a new video so i have a question for you are you using link if you're using link this video applies to you are you using anywhere this arrow symbol thingy functions actions this applies to you see we are using a language it's very flexible that allows us to do things like this and i'm going to talk through through the code in a second but those things have some drawbacks and we're going to see how closures can be a drawback now what do i have here i have a program.cs and let me just change the debug that has a new application it music app and then it uses the run method in the run method all it really does is it calls this git number over number so we get numbers of a number uh which all it really does is it gives it a number variable a number argument and then it does a count on this list of numbers and it gives us the number of numbers that are over a specific number i could have named those things better so for example in this case if i say get numbers over number 400 it should give me anything that is more than 400 which should be 599 assuming this is maxing out to 999 which is what it is so this code looks absolutely fine i see nothing wrong with it so what i want to do now is we're going to stick a breakpoint here and i'm gonna start the debugger and the debugger in writer has this tab called memory i'm gonna go here i'm gonna say load classes and i'm gonna search for like everything looks fine but here i can see all the allocations and i can go here and i can say display and i see this display class here and i have one display class that has allocated 24 memories on the heap 24 bytes sorry and if i expand this i can see the pointer to the allocation um and the address sorry and you can see that my number this thing here has been allocated there but why and why through a display class right this doesn't make any sense in fact if i change this count to its link version and i do the same thing again i just debug the code and nothing else has changed and i go to memory and unload this display class doesn't exist and this allocation doesn't exist so why is this happening well this display class that you just saw is a closure class the reason why it's happening is because we're passing in out of scope and the scope is anything in this our function this lambda function from the outer scope in that scope but the lambda needs to somehow remember that this exists and that this variable exists it can't just pass it down by value so instead it's going to create a class make a field in that class allocate it and then pass that down so if i move that from an argument and let's just delete that and make it a local variable what do i know as an engineer writing c sharp well i know that local variables like this are supposed to be allocated on the stack so i shouldn't be able to see them here however i'm doing display and i still see a display class here and this display class has the number in it why well closures is why if i convert this into a constant or if i remove the link which means it doesn't have to be captured in that scope somehow so the display class isn't created then the allocation is removed and we can just quickly see that if i go again to the memory and if i say uh display you'll see that there's no display class having allocated that and i'll show you very quickly why this actually happened as well i'm gonna use um shoplab.io which will show us the lowered version of the code if you don't know what lowering is in c shop you can check the video i already have on that it is a process during compilation where high level features are being converted into lower level features and inlining a constant is one of those operations that will take place so if i just copy this full code and i go to the shoplab.io website and i just paste it here i should be able to see that there is no display class or whatever and as you can see this constant number doesn't actually exist on the right side it doesn't exist because it has been inlined as a constant however if i remove the const keyword you now see that i have a display class which is being generated for me to be able to allocate that number as a class level variable which will actually locate on the heap so it can be passed down to this arrow function and you can see that we're renewing app this display class here actually you cannot see it because i have my face there so let me quickly change this by creating a few fake methods i made them to push the toilet to scroll higher further up so you can see that display class is being nude app number is being allocated here and then it's being used to do an enumerable.count on that and this is effectively a closure this class created to allocate that thing that you're passing from out of the scope is a closure if i do the other thing where i actually take this from here and i actually turn it back into a variable so it's allocated you know through the display class and instead of doing that i'm moving it inside the scope and that's not possible most of the time but when it is i'm gonna show you how that looks like so this should be uh return and they should be newly lined and they should be here so now it's available like it was before and like we said we would expect it to be allocated on the stack but it was allocated on the hip because of the closure so if i put a breakpoint here now and i run this and i go to the memory and i load classes and i say display you don't see the display class and that's because a closure won't be created and that's because now it is in the scope of the lambda of the function so it doesn't need a display class to remember where it was and how you know how it works with our function uh so for that reason it's no longer any location we need to worry about closures can have other side effects as well and i'm very happy to observe them into a more advanced video but as a very basic understanding this is what a closer it is whenever you see this display class and i'm sure you've seen them in stack races before if you've debugged an application then you have a closure which is allocating some memory and if you need to save memory and remember you might be saying one thing here and say 24 bytes that's nothing but how many times are you using a where an account and then maybe a select and other things involving other viruses as well from out of scope and you're using them well all of them add up and i had scenarios where i actually had to optimize there because it really is a true thing that you can get wrong and it actually does add up to effectively what is death by a thousand cuts now if i can give you a tip as part of this video again let me do the following i'm gonna convert it to what it was before to where we have it as an argument and you might be like well nick i am i'm relatively new to the to c-sharp i'm new to the concept and i you know i don't i didn't know about this and how do i identify you know you told me whenever i sit here then i should be worried about it but then sometimes you can change this to extract it and then i have to keep you know it's hard to keep track of everything so for that what i use is and i go to a nuget for that clr heap allocation analyzer this fella over here is a nuget package that you can install to your um to your code base and the moment i install it i say two things this went yellow this went yellow this tells me that there's a heap allocation of closure captures member the variable number and here it tells me that the compiler will emit a class to hold this as a field to allow capturing of this closure so now i know from an analyzer and i have a video on what an analyzer is in c sharp and i'm actually using the same example as well so if you want to check that out as well to learn more about them please be my guest and you can use this as a helper to help you see and detect those allocations and those closures they're also going to help you with boxing and unboxing which i'm going to cover in a separate video and you can see for example boxing here nothing to worry about it as part of this video again if i remove that and i move it here and i say 400 and i remove that it will still notify you about the closure but the moment you turn it into a const one it goes away because it knows that this will be in line and also if you were to move it here then you can see that also the warning goes away and this is not unique to this specific thing this is across your whole project whenever you're newing up an object for example if i go to program.cs it now tells me that explicit new reference type allocation so it's going to tell me that this application class will be allocated it's a great tool not something you need to worry about most of the time and to be honest i would change this from a warning to maybe informational you know a green squiggly line or even a green dots just so you can get introduced to the concept and then later um you know maybe turn it into a warning to see how you can solve it but this is all i want to talk about in this very first video just a very introductory video without any insanely accurate technical terms i hope you understand what it is and i hope you're able to detect them in the future and understand what people mean when they talk about closures that's all i have for you for this video thank you very much for watching special thanks to my patrons for making videos possible if you want to support me as well you're going to find it in the description down below leave a like if you liked this video subscribe for more content like this ring the bell as well and i'll see you in the next video keep coding
Info
Channel: Nick Chapsas
Views: 74,286
Rating: undefined out of 5
Keywords: Elfocrash, elfo, coding, asp.net, .netcore, dot net, core, C#, how to code, tutorial, asp.net core, csharp, lesson, microsoft, microsoft mvp, .net core, nick chapsas, chapsas, asp.net core 3, .net core for beginners, c# closure, .net closure, closure class, display class, memory allocation, memory optimized C#, What is a Closure in C#, What is a Closure in C# and how it is wasting your memory, dotnet, .net
Id: h3MsnBRqzcY
Channel Id: undefined
Length: 12min 0sec (720 seconds)
Published: Thu May 06 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.