It's a failing of many type systems of older languages (except Pascal).
The best way in many languages for flags is using unsigned integers that are botwise-ORed together.
In pseudocode:
Object someObject;
foo (someObject, Object.Flag1 | Object.Flag2 | Object.Flag3);
Whatever language you are using, it probably has some namespaced way to define flags as `(1 << 0)` and `(1 << 1)` etc.
If you really need all of that I think I'd go with a separate object holding all of the options:
options = new SerializeOptions();
options.PrettyPrint = true;
options.Flag2 = "red"
options.Flag3 = 27;
serialize(someObject, options)
So 1 line of C/C++ becomes 5 lines of Java/C#? That sounds about right! :-) Though I'm sure we can get to 30 if we squeeze in an abstract factory or two!
You can do the above in C#, I haven't written Java in a decade so can't comment on that. I don't really understand your argument though - the options approach is extremely readable. You can also do the options approach in C or C++. The amount of stuff that you can slap into one line is an interesting benchmark to use for languages.
It's always crazy to see languages like C being able to beat high-level languages at some ergonomics (which is usually their #1 point of pride) just because C has bitfields and they often don't.
> The best way in many languages for flags is using unsigned integers that are botwise-ORed together.
Why is that the "best" way?
> Why is that the "best" way?
"Best way" is often contextual and subjective. In this context (boolean flags to a function), this way is short, readable and scoped, even in C which doesn't even have scoped namespaces.
Maybe there are better ways, and maybe you have a different "best way", but then someone can legitimately ask you about your "best way": `Why is that the "best" way?`
The only objective truth that one can say about a particular way to do something is "This is not the worst way".
It's simple, efficient, and saves space in memory. While not as big a deal these days where most systems have plentiful RAM, it's still useful on things like embedded devices.
Why waste a whole byte on a bool that has one bit of data, when you can pack the equivalent of eight bools into the same space as an uint8_t for free?
Sure, that works when trying to conserve memory to the degree that a few bytes matter, but the downside is that it's more complex, less obvious.
I've done exactly what you propose on different projects but I would never call it the "best" method, merely one that conserves memory but with typical trade-offs like all solutions.