Checking for unions between flags in C#

2020-06-12

I spent a lot of time thinking this through yesterday and a lot of time today googling solutions, so I figured I’d write a short blog post about it in case it helps anyone else out.

Notes:

Problem

Research

As mentioned, StackOverflow and Google were surprisingly little help on this. Most answers and pages took the route of iterating through the flags bit by bit and checking them in a loop, but I stumbled slightly on skipping ShapeTypes.None. I knew that bitwise operators are often used with flags, but I couldn’t make it work in my head yesterday. Today it just sort of popped in there, probably owing to letting it rattle around my subconscious overnight. I was not in a good headstate yesterday for smart-people shit.

Solution

It turns out to be trivial to check for a union between flags using bitwise operations. You just take a and it with b to create c. c now contains only flags that were in both a and b. What I didn’t think of until today was casting c to an int, and checking to see if it’s greater than 0. If it is, by definition, there were flags in the union. If c is 0, then there were no flags in common.

Boom, done, no iteration, no hasflag().

public bool DoFlagsOverlap(ShapeTypes a, ShapeTypes b)
    {
        ShapeTypes c = a & b;
        if ((int)c > 0)
        {
            return true;
        }
        else return false;
    }

Kids stuff

I know, not a revelation. This, as far as I can remember in the deep past, is how most people use flags in Unity, but for some reason (possibly because I was searching for C# answers rather than Unity answers) I never found a similar solution, I had to construct it mentally myself, this time.

I don’t play around with bitwise operations much, obviously. I probably would have nailed this in a couple of minutes if I did. Maybe I should finally learn some C++, that might help me think of lower-level solutions occasionally.

I also realize now that I could probably one-line the return. Something like

return (int)c > 0 ? true : false;

but hey, it works.


Related


comments powered by Disqus