Recently I needed a way to store a finite list or error messages that could potentially occur during an async process.
I could have implemented something like - creating a relational table structure, store them as a JSON file etc. All of the alternatives felt a bit like 'overkill' for reasons I won't go into here. So I decided to opt for a Bitmask. Why? Well, essentially, bitmasks are a great way to store a large amount of 'information' in a small space.
Here are the potential errors that I needed to log.
- invalidName
- invalidDate
- invalidTime
- invalidType
- invalidRange
- invalidState
So what Bitmasking allowed me to do was to assign an integer value to each of the potential errors. So:
- invalidName = 1
- invalidDate = 2
- invalidTime = 4
- invalidType = 8
- invalidRange = 16
- invalidState = 32
Usage
In C# land we would implement something like this:
using System;
public class Program
{
static int _errorTotal = 0;
public static void Main()
{
//simulate some errors
_errorTotal += (int)Errors.Name;
_errorTotal += (int)Errors.Date;
_errorTotal += (int)Errors.Time;
_errorTotal += (int)Errors.Type;
Console.WriteLine("Error total: {0}", _errorTotal); // this is what we persist
Console.WriteLine("Error list: {0}", (Errors)_errorTotal); // this is how we read the data back out
}
// Holds the value of each of the error types
[Flags]
public enum Errors
{
Name = 1,
Date = 2,
Time = 4,
Type = 8,
Range = 16,
State = 32
}
}
Output:
Error total: 15
Error list: Name, Date, Time, Type
We can now see how storing just one integer value, you can gain access to any combination of errors that occurred during the async process.
Note: Like I said at the start, this is a great way of storing a finite list of 'stuff' - for particularly long lists of 'stuff', you might want to cast your [Flag]
enum to (long)
:
[Flags]
public enum Errors : long
{
Name = (long)1,
Date = (long)2,
Time = (long)4,
...
Top comments (3)
Something that makes things a little more clear and easy to work with is if you define the enum in terms of powers of 2.
Sadly, C# lacks a power operator.
Alternative syntax to set flags.
Alternative syntax to define them using C# 7 binary literals
Or shift syntax