Introduction
Working with enum
s is a very interesting option in several situations, that one that I prefer the most is to avoid hardcoding a string
. Another interesting one for me is the possibility of modifying the behaviour of a class or a control giving it a sequence of orders with an enum
that accepts more than one value.
The Source of the Idea
The first time when I was developing with Reflection, I discovered the way the System.Type.GetType().GetMethod()
method has a parameter whose type is the enum System.Reflection.BindingFlags
, and this method accepts more than one value or the Enum
if necessary to specify the behaviour of the method.
System.Collections.ArrayList list = new System.Collections.ArrayList ();
System.Type type = list.GetType();
System.Reflection.MethodInfo mi = type.GetMethod
( "Sort", System.Reflection.BindingFlags.IgnoreCase |
System.Reflection.BindingFlags.Public );
mi.Invoke ( list, new object [] { } );
Background
When I saw the values of the members of the enum
s and some documentation about it, I clearly noticed that the trick is to develop an enum
with values such that the addition of any combination is unique.
This is the way most of the .NET Framework enum
s are defined. To be precise, most of those that I have seen, as for example the Binding Flags enum
, are defined with values in a series of 2^n, having 0 as default value.
public enum PlanesTypes
{
NoPlane = 0,
F15_Eagle = 1,
F18A_Hornet = 2,
F14 = 4,
MIG29_Fulcrum = 8,
F16_Falcon = 16,
F127_Phantom = 32
}
public enum DaysOfWeek
{
NoDay = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64
}
Declare an enum
this way, you always can add as many values of the enum
as you like and you can be sure you will be able to recover the selected values when needed.
SetMyFavoriteDaysOfTheWeek ( ( DaysOfWeek ) 13 );
SetMyFavoriteDaysOfTheWeek
( DaysOfWeek.Friday | DaysOfWeek.Saturday | DaysOfWeek.Sunday );
SetMyFavoriteDaysOfTheWeek ( DaysOfWeek.Saturday | DaysOfWeek.Sunday );
SetMyFavoriteDaysOfTheWeek ( DaysOfWeek.Monday | DaysOfWeek.Tuesday |
DaysOfWeek.Wednesday | DaysOfWeek.Thursday | DaysOfWeek.Friday );
What I have done is a static
function that given an enumType
and a value
returns a System.Collections.ArrayList
with the values resulting from desegregating the enum value
given as a parameter.
public class EnumReader
public class EnumReader
{
public static System.Collections.ArrayList GetValuesFromEnum
( System.Type EnumType, int EnumValue )
{
System.Array EnumValues = System.Enum.GetValues ( EnumType );
System.Collections.ArrayList valuesList =
new System.Collections.ArrayList ( EnumValues.Length );
System.Collections.ArrayList SelectedList =
new System.Collections.ArrayList ( );
System.Collections.IEnumerator enumerator = EnumValues.GetEnumerator();
while ( enumerator.MoveNext() )
valuesList.Add ( ( int ) enumerator.Current );
valuesList.Sort ( new ReverseOrder() );
enumerator = valuesList.GetEnumerator();
while ( enumerator.MoveNext() )
{
if ( EnumValue >= ( int ) enumerator.Current )
{
EnumValue -= ( int ) enumerator.Current;
SelectedList.Add ( ( int ) enumerator.Current );
}
}
return SelectedList;
}
internal class ReverseOrder : System.Collections.IComparer
{
public int Compare ( object x, object y )
{
return ( ( int ) y ).CompareTo ( ( int ) x );
}
}
}
In the image below, it can easily be seen that the binary addition can be decomposed in the single values of the enum
. And it is also clear that if the values of the enum
are declared as 2^n, the result of the addition of any combination of values are unique.
Create an enum
this way using a function like this. It is very easy to create behaviours on classes, controls or avoid arrays with many values.
In my case, I have an ASCX control with 7 different div
s that contain radio buttons, checkboxes with prices, and specific information (and there are a lot of combinations with 7 elements) that must be shown or hidden depending on specific and complex business rules, so I thought that putting an integer value in a member of a Business Entity was a clear and easy way to do it, because in the end you are adding Integer values.
That's all. I hope someone finds it useful.
Spanish Computer Engineer who is working with Microsoft Technologies.
Currently working and living in Sydney, Australia.