There's been a lot of blogging going on about the values of Enums. One of my favorite articles on the subject has always been Extolling the Virtues of Enumerated Types that appeared in 2001 in msdn magazine. But before I can say, “And that's about all I have to say about that“ Forrest Gump Style, I've got to mention using enums with Bitwise operations. This is something that I use often to express a value that is a composite of other possible values.
For Example, I use this is with my ContainerWatch application here at the Virginia International Terminals. I need store which Container event a user wants to receive email notifications for. They can elect to receive all, none or any combination of the following events, which are represented in the following enum:
[Flags]
public enum WatchListEventEnum
{
None = 0x00, // Binary 000000
Arrive = 0x01, // Binary 000001
Ready = 0x04, // Binary 000100
Depart = 0x02, // Binary 000010
FumigationComplete = 0x08, // Binary 001000
TermTermOut = 0x10, // Binary 010000
TermTermIn = 0x20 // Binary 100000
}
Now I want to store this information in a SQL Server table, and I do have them also stored in a SQL Tables as integers, but I don't want to deal with join tables to see which events users are watching for which shipping container. So, I instead store one int value, which is a bitwise OR of all of the events they've chosen. I can use the following logic to determine if a given event is represented in a given int value.
public static bool IsWatchListEvent(int bitmask, WatchListEventEnum evt)
{
return Convert.ToBoolean(bitmask & (int)evt);
}
And if I want to get the int value to store in the database, I can use this function:
public static int GetEventBitmask(bool isArrive, bool isReady, bool isDepart, bool isFumigationComplete, bool isTermTerm)
{
int retVal = (isArrive) ? (int) WatchListEventEnum.Arrive : 0;
retVal |= (isReady) ? (int) WatchListEventEnum.Ready : 0;
retVal |= (isDepart) ? (int) WatchListEventEnum.Depart : 0;
retVal |= (isFumigationComplete) ? (int) WatchListEventEnum.FumigationComplete : 0;
retVal |= (isTermTerm) ? (int) WatchListEventEnum.TermTermIn + (int) WatchListEventEnum.TermTermOut : 0;
return retVal;
}
I can even use the bitwise & operator from SQL like so:
((WL_NEW_CTR_EVTS.WL_CONTAINER_EVENT_TYPE_ID & vw_ACTIVE_WATCH_CONTAINERS.WL_CONTAINER_EVENT_TYPE_BITMASK) > 0)
Now, a database purist may not advocate this approach, but it works great for me in certain situations. Okay. That's about all I have to say...
-Brendan