Reflecting Enumeration Information
The thirteenth part of the Reflection tutorial examines the methods of the System.Type class that provide reflection specific to enumerations and their constants. These methods, introduced in .NET 3.5, provide similar functionality to the Enum class.
Enumerations are useful for grouping together sets or sequences of numeric constants, which can be used in place of magic numbers to make your code easier to understand and maintain. Information about an enumeration and its constants can be obtained using the methods of the Enum class in all versions of the .NET framework. You can also use standard reflection methods, such as those for reflecting fields or reflecting all members to extract details about the enumeration's defined values. With the introduction of the .NET framework version 3.5, Microsoft added some specific reflection members for dealing with enumerations. These will be the focus of this instalment of the tutorial.
We need a sample to work with for our examples. We'll use the simple type shown below, which holds the months of the year, numbered one to twelve, using a 32-bit integer-based enumeration.
public enum Month
January = 1,
Obtaining Enumeration Constants
When you want to get the details of the constants that are defined within an enumeration there are several reflection methods available via the System.Type class. The first that we will look at obtains the name of a specific constant as a string. This GetEnumName method accepts a single argument containing the numeric value of the constant. The parameter is defined as an object, rather than an integer, to allow names to be extracted from enumerations that are not based upon the default 32-bit integer type.
Type type = typeof(Month);
string name = type.GetEnumName(3); // "March"
If you simply need a list of the names of the constants that are defined in an enumeration, you can use the GetEnumNames method. This returns the names as an array of strings. The name array is sorted according to the numeric value of each constant using unsigned binary values. This means that negative values appear after positive ones. If two members share the same numeric value, the order they appear in cannot be guaranteed.
string names = type.GetEnumNames();
Finally, you can retrieve an array of the values from an enumeration using the GetEnumValues method. This returns an Array object containing the values in their defined type, in our case as Month values. You can use the standard methods of the Array class to read the individual values or obtain an enumerator. Alternatively, you can convert the object to a simple array using the Cast and ToArray operators of Language-Integrated Query (LINQ).
Array values = type.GetEnumValues();
Month months = values.Cast<Month>().ToArray();
Checking if an Enumeration Value is Defined
Another useful reflection method allows you to determine whether a specific value is defined within an enumeration. The IsEnumDefined method accepts a single argument holding the value to be checked. This can be the numeric value or a string containing the name of a member to be found. If the enumeration contains the specified value, the method returns true. If not, it returns false.
bool is4Present = type.IsEnumDefined(4); // true
bool isAprilPresent = type.IsEnumDefined("April"); // true
bool is13Present = type.IsEnumDefined(13); // false
bool isMondayPresent = type.IsEnumDefined("Monday"); // false
Obtaining the Enumeration Base Type
The final Type method that we will consider obtains information about the entire enumeration, rather than its constituent values. Enumerations are, by default, based upon the 32-bit integer type, Int32. However, this can be changed to other integer types. If you need to find out what the underlying numeric type of an enumeration is, you can obtain a Type instance for it with the GetEnumUnderlyingType method, as follows:
Type enumType = type.GetEnumUnderlyingType(); // Int32
27 May 2012