Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flags enum & bitwise operations vs. “string of bits”

A fellow developer suggested we store a selection of days of the week as 7-character string of 1’s and 0’s, i.e. “1000100” for Monday and Friday. I preferred (and strongly suggested) a solution with a Flags enum and bitwise operations, I think it's a cleaner way of doing this, and it should be easier to understand for other developers.

  [Flags()]   public enum Weekdays : int   {     Monday = 1,     Tuesday = 2,     Wednesday = 4,     Thursday = 8,     Friday = 16,     Saturday = 32,     Sunday = 64   } 

However, as I started to implement a sample solution, I realized that maybe the simple string approach was easier after all: Certainly the bit-string is more obvious than “17” if you’re just looking at the data. And I find the C# bitwise operations counter-intuitive and extremely verbose:

Weekdays workDays = Weekdays.Monday | Weekdays.Tuesday; if ((workDays & Weekdays.Monday) == Weekdays.Monday)  {...} 

Of course this could be wrapped nicely into extension methods, but then we suddenly end up with at least the same number of lines of code as with the string-solution, and I can hardly argue the bitwise code is easier to read.

That being said, I still would go with a flags enum and bitwise operations. The key benefits I can think of are

  • Better performance
  • Less space needed for storage

So how do I sell the bitwise solution to my colleagues? Should I? What are the other benefits of using this method over strings? After completing the sample project, I found that the team still opted for the string-based solution. I need some better/stronger arguments. Why should you use Flags enums rather than simple bit-strings?

like image 417
Jakob Gade Avatar asked Aug 17 '09 02:08

Jakob Gade


People also ask

What is a Flag enum?

The idea of Enum Flags is to take an enumeration variable and allow it hold multiple values. It should be used whenever the enum represents a collection of flags, rather than representing a single value. Such enumeration collections are usually manipulated using bitwise operators.

What is the role of Flag attribute in enum?

The [Flag] attribute is used when Enum represents a collection of multiple possible values rather than a single value. All the possible combination of values will come. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.

What is the use of Flag in C sharp?

Flag variable is used as a signal in programming to let the program know that a certain condition has met. It usually acts as a boolean variable indicating a condition to be either true or false.

What is Flag in VB net?

In general, "Flag" is just another term for a true/false condition. It may have more specific meanings in more specific contexts. For instance, a CPU may keep "arithmetic flags", each one indicating a true/false condition resulting from the previous arithmetic operation.


2 Answers

Benefits of using Flags enum:

  • Standard approach: "They are the correct design to use when multiple enumeration values can be specified at the same time."
  • Intent is clear
  • Maintainable -- new programmers should pick this up easily
  • Easily extensible -- support for new flag combinations (e.g. weekend)
  • Fast

Negatives of using Flags enum:

  • Data representation for humans hard to understand (e.g. what flags are set for 17?)


Benefits of using string of bits:

  • Easy for programmers to see which bits are set in string

Negatives of using string of bits:

  • Non-standard approach
  • Harder to understand for programmers unfamiliar with your design
  • Potentially easier to set "garbage" values (e.g. stringValue = "Sunday")
  • Needless string creation
  • Needless string parsing
  • Additional development work
  • Reinventing the wheel (but not even a round wheel)


How important is it really to be able to look at the string of bits to see what is set? If it's hard to know that 17 is Monday and Friday, you can always use calculator and convert to binary. Or add some sort of string representation for "display" (or debugging) use. It's not that difficult.


It also seems to me that if you are going to make the string of bits approach solid then you will need to do quite a bit of encapsulation to bring it up to a level of abstraction that the Flags enum already provides. If the approach is to simply manipulate the string of bits directly then that is going to be hard to read (and understand) and probably error prone.

e.g. you may end up seeing this:

days = "1000101"; // fixed bug where days were incorrectly set to "1010001" 
like image 178
Randy supports Monica Avatar answered Sep 21 '22 21:09

Randy supports Monica


You shouldn't be creating non-standard datastructures to replace a standard data structure (in this case, the DayOfWeek builtin enum). Instead, extend the existing structure. This works essentially the same way as the bit flags method you were talking about.

namespace ExtensionMethods {     public static class Extensions     {         /*          * Since this is marked const, the actual calculation part will happen at          * compile time rather than at runtime.  This gives you some code clarity          * without a performance penalty.          */         private const uint weekdayBitMask =             1 << Monday              | 1 << Tuesday             | 1 << Wednesday             | 1 << Thursday             | 1 << Friday;         public static bool isWeekday(this DayOfWeek dayOfWeek)         {             return 1 << dayOfWeek & weekdayBitMask > 0;         }     }    } 

Now you can do the following:

Thursday.isWeekday(); // true Saturday.isWeekday(); // false 
like image 44
Imagist Avatar answered Sep 23 '22 21:09

Imagist