BrandGhost

The Ultimate Beginner's Guide to Flags Enums in CSharp

In our previous videos, we looked at the basics of Enums in C# as well as how to parse them from strings. Now that we know the basics, what's this about... flags?! Check out this video for a flags Enum tutorial in CSharp! Have you subscribed to my weekly newsletter yet? A 5-minute read every weekend, right to your inbox, so you can start your weekend learning off strong: https://subscribe.devleader.ca Check out more Dev Leader content (including full in-depth articles with source code examples...
View Transcript
so many new developers in C get to using enums and then they start declaring their own enums and having a lot of fun with them but what you might not have realized is that you can actually use enums as flags and this isn't something that's totally common in a lot of C SHP code but something that exists and if you've had any experience doing some lower level programming especially anything embedded Flags in something like an enum is extremely common and to elaborate a little bit further Flags allow us to combine different values of an enum to overlap them it's a lot easier to understand if you're thinking about the binary representation of flags and turning bits on and off and that's why in an embedded setting it can be really handy to represent a handful of different states all with one number simply by toggling bits and we can do the same thing in C so instead of having an enum that represents a contiguous range of values on a fixed set like days of the week for example what we could do instead dead is have an enum that declares different settings that we can toggle on and off overlap and check individual flags for so in this video we're going to explore how we set up flags for enums just like how I explained and walk through some examples of how that looks before I jump over to visual studio just a quick reminder to subscribe to my free Weekly Newsletter where I send out different software engineering topics as well aset content I try to put out exclusive articles as well as Early Access to some of these YouTube videos and I include things like a weekly challenge for you to work through as well like I said it's totally free and I'll include a link to that in the comments below so you can check that out okay enough rambling for me let's go check out how we can convert our enums into Flags starting with the base case of how we declare an enum we have days of the week here that I have commented out and this is from a previous video If you haven't seen that yet I would suggest clicking the link above and then coming right back to this video to continue on if you're still new with working with enums now when we declare an enum this way it allows us to get automatically incremented values for each item in the enum so Monday would start at zero Tuesday 1 Wednesday 2 and so on and so forth and that's going to be something important to keep in mind as we look at how we can go create Flags this example that I have on my screen now is an example enum that I've created called my flags and we use the same syntax so public enum my flags and then what I've gone ahead and done is set a b and c as the different values that we have for the enum I have some commented out code which I'll explain in just a moment but I wanted to call out as well that we can put this Flags attribute on top of our enum when we want it to be treated like flags all right so what's going on with the comment toot code why do I have this declaration this way as well as this one here well I mentioned that in a normal enum when we're declaring things and having the values be initialized automatically and incremented for us what ends up happening is that a would start at zero B would go to one C is two and D is three in this case when we're thinking about working with flags though we want to think about the binary representation of the numbers and the reason that we do that is because when we're working with flags we're going to be toggling on and off bits and looking at if a bit is set or not and the tricky thing about doing automatic incrementing enum values is that something like d when it's equal to three is actually going to be represented by one one in binary and that means that by default it kind of has two flag bits turned on to represent D and that's a little bit weird so I would recommend that if you're working with flags you get in the habit of explicitly declaring what the values are so now if you look at how I've declared my flags and I have a b c and d here set to these hex values we can see that I have 1 10 100 and a th000 and it's visually indicating that we have these different bits that we can could have turned on now I did mention that this is hex we usually see that when people are declaring numbers in C and their hex you have this 0x prefix but when we're dealing with flags you can use hex if you'd like to but we can also use binary representation by putting a b here and that's going to be a lot more in line with what I was saying in the beginning of this systems that are embedded would be using binary Flags just like I've indicated here where this is one this represents two this is going to be four and this is eight and that way if you had a combination of them like a and b being turned on at the same time this would be 1 one and that's because A and B are both turned on at the same time because enums are 32-bit integers by default if you don't have many states you can totally get away with using a hex representation but just to be consistent with the intro of this video where I was talking about embedded systems I'm going to go ahead and leave this as binary it's also going to simplify us looking at the values that we have here when we go to look at some of the examples above so with that said let's go look at the examples above when we're working with flag enums it's going to be a lot more common for us to be working with binary operators and we're used to Boolean operators where we have something like ore which is two pipes but in this case we're using an ore which is just a single pipe and that's because we're going to be doing binary operations here the same thing is true with this and instead of saying a Boolean and where we're taking two conditions and adding them together we're doing a binary operator here so let's walk through these examples I've declared on line 56 a variable called Flags a with c and what we have on the right hand side is that I'm using a binary or of flag A and C so the result of this is that we should have both the bit for a and the bit for C turned on at the same time so what would that look like well if I scroll down a little bit lower we have a as one on the far right hand side and C which is going to have 1 0 0 so if we have a and C turned on at the same time it would mean that we have this bit turned on for C there's no common bit turned on for a or C here so that remains a zero and then a would be turned on in this position so we would have one 0 1 and of course the decimal value for that is going to be 4 + 1 which is 5 so if I scroll back up we would expect that we have something equivalent to five When A and C are both turned on at the same time well what happens when we use an and operator and in this case is going to allow us to check if we have bits turned on in the same position now this is going to be a little bit interesting because we just said that flag a and flag C are both independent bits that is they don't have any bits that overlap they're just single bits in different positions so if we were to add these together and there's no common overlapping bits that should mean that we have zero we would need to have at least one overlapping bit to have some resulting bit turned on after adding them together and therefore the result would be something other than zero but because there's nothing overlapping it means that every bit will be turned off when we and these two things together and as a result we should see Zero here now before I go run this program to see these results let's go check a final example so we can talk about them all at the same time I've created a slightly more complicated example where we're taking some variable and assigning a b or c all at the same time to this flag variable and that's going to mean that we have a bit turned on in position one 2 and three so if you were to think about that as eight bits in a bite it would look like the first three bits are turned on then a zero and then the top bits would all be turned off so this is going to be representing flag a this is flag B and this is flag C the or operator in between them just allows us to have them turned on at the same time if we wanted the decimal value for what this is going to be it's going to be 4 + 2 + one and that's going to be seven so we know that the value of some Flags is going to be seven in decimal or represented by the first three bits being turned on that's pretty straightforward but what do we do with this when we're dealing with flags in C how the heck are we supposed to do anything useful with these flags well we can check to see if different flags are turned on or off so in the next two lines I have an example of checking to see whether a flag is on and we talked about the and operator allowing us to check to see if a bit is on or off by using the the and operator we're only going to get bits turned on when they're overlapping so what we could do is check the base of some Flags which is going to be these three bits and then and that with some flag that we're interested in so the result of doing an and operation like this one that I have highlighted some flags anded with a is going to check to see if we have a bit turned on in position one which is where a is so that's going to be this bit here we know based on how we've defined some flags that a is part of that and we see a one here so if we were to and some flags with a we would get one bit turned on in this position and that means if we want to check to see if a is actually on we just go compare that to my Flags a I'll indicate in another example why we can't just check to see if the result is one it would work in this case but it's not universally going to apply the next scenario I want to look at is checking to see see if flag D is on now we know because we can see the code above that we only have a b and c turned on for this variable so what does that actually mean when we go to check if D is on well we know that D is in the fourth position and if we look at the value of some Flags we can see that position four is a zero so this would be the equivalent to a 1 0 0 0 and we're anding that with 0 1 1 and that means that that fourth position because there's a zero being added with a one in that position the result of that is zero so this evaluates to zero and of course that's not going to be equal to the value of flag D so we would expect to see that flag D is going to be turned off and I wanted to add a third example here to illustrate why we can't just put a one here for checking when a flag is on you can see already that Visual Studio is telling us it's not even going to compile and if you wanted to try faking it into compiling you could go ahead and do some casting here now that compiles but it's not going to make sense when we go to evaluate it so let's walk through it together we know that some Flags which is here is declared as having a b and c Flags turned on and like we've said that's the first three bits when we go to and those first three bits with flag C that means we're checking to see if the third position which is what flag C is is turned on and the result of that is going to be this number here and as we can see we have a one turned on in the third position because that was the only bit that was overlapping between flag C and some Flags now this bit being turned on means that this entire number is equal to four so that means that we can't just check for a True Result and we can't just check to see that it's one like it's on or off it does mean that we need to have a four here but this is kind of silly because we don't have to do casting of my Flags to get four we simply just want to check if my flags. C is turned on because that's going to be built in to give us that third position turned on which is a decimal value of four so that's why we need this syntax here when we're anding a particular flag and checking if the result of that is the flag that we're checking it looks a little bit redundant because we have have the same thing in two spots but that's because we need to check if that bit is turned on after all right now that we've explained all of these examples let's go look at the resulting output when we run the program okay so here's the program output once we run it the first example that we were looking at is Flags a being turned on with flag C and that's this part here and as we can see the result of that is a and C so it's really cool that in C when we're doing two string on an enum value like this with flags that it knows to Output that as a and C separately we're not seeing some weird numeric representation of that or anything else it's giving us mostly a human readable version of those flags being turned on and off so this is extremely valuable when it comes to debugging because a lot of the time we're using enums to have more human readable data if you wanted to know the numeric representation of this just remember that we had a being turned on in position one and C in position three and that would mean that in decimal we have a four plus a 1 here so the result of this is actually the numeric value five now this was the result of an or operator but the next example was using an and operator and like we were talking about a and C are bits turned on in very different positions and that means that when we use the and operator there's nothing that's overlapping between them so the result of of that is zero and that makes a lot of sense because there are no bits that overlap and then we said well what's the point of all of this if we have Flags how can we take advantage of using them so we declared a variable that was called some flags and then we turned on a b and c and the two- string representation of this is super handy in a video like this but if we wanted to know the numeric value like I said before we would have a bit turned on in position one in position two and position three so three ones turned on in the binary representation of this value so if we wanted to check if flag a is on what we had to do was and some flags with flags. a but that wasn't enough we had to actually check if the result of that was equal to flags. a and we can see that that result is true when we're checking if flag D is on when we're looking at the two string representation of this it's really really obvious that it's not but when we're looking at the numeric representation or just looking at the code it might not be totally obvious but we did the same thing we said some Flags ended with flag D and then we had to check if that was equal to flag D it turns out flag D is in fact not on and finally we added this third example for if flag C is on of course we can see it printed out here but the way that we Prov this was anding flag C with some Flags which would check if the third bid is turned on and it is and then we check to see if that result is equal to flag C which is the third bit being turned on and that's why we see true here and that's going to wrap up this video using enums as Flags the big differentiator between using Flags or just a normal enum is that with a normal enum a lot of the time we're talking about discrete states that we want to be in so something like days of the week I always think is a great example because there's a finite discreet set of days of the week flags on the the other hand allow us to combine these so if you needed a state that could be represented by multiple enum values at the same time you can mark it as flags and then like we showed in here you could either use a hex representation if you don't have many states or we used a binary representation to really give us that fill in our Eno now if you think about it I said that days of the week was not a flag but you could in fact have an enum declared for days of the week that is a flag what if you wanted to have something like auler a on job if you wanted to be able to turn on Monday Tuesday Wednesday and maybe leave the other days of the week off you could use something like flags with days of the week and then turn those days on it's all about how you intend to consume the enum information but again the differentiator is that Flags allow us to have a combination of State whereas a normal enum that's not the intention now in this series I've also said that I think that there are situations where people are not using enms properly and that's sort of as this side effect of us being able to have string and numeric representations of enom so stay tuned to watch this next video where I'll talk about some of the pitfalls of using Enos thanks and we'll see you next time

Frequently Asked Questions

What are flags enums in C# and how do they differ from regular enums?

Flags enums in C# allow us to combine different values of an enum by using bitwise operations, which is not something that regular enums do. Regular enums represent discrete values, like days of the week, while flags enums enable us to represent multiple states simultaneously by toggling bits on and off.

Why is it recommended to explicitly declare values for flags enums instead of using automatic incrementing?

It's recommended to explicitly declare values for flags enums because automatic incrementing can lead to overlapping bits in binary representation. For example, if you let the enum automatically assign values, you might end up with a value that has multiple bits turned on, which can cause confusion when you're trying to use bitwise operations.

How can I check if a specific flag is set in a flags enum?

To check if a specific flag is set in a flags enum, you can use the bitwise AND operator. You would AND the variable containing the flags with the specific flag you want to check, and then compare the result to the flag itself. If they are equal, it means that the flag is set.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload