Enumerations are basically used to write clean and readable code for a set of constant values. I won't be explaining the basics of enumeration but instead going to the next level. We'll see in this article how to manipulate the values, names and attributes using Reflection at run time.
First let's take a simple Enum. We'll be using it throughout the article for demo purposes:
public enum TestEnum
{
[Description("Undefined Enum")]
Undefined = 0
[Description("Enumeration 1")]
Enum1 = 1,
[Description("Enumeration 2")]
Enum2 = 2,
}
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Here is the list of operations with snippets that we can perform to use the TestEnum in various ways.
Get the name of the Enum
Console.WriteLine(TestEnum.Enum1.ToString());
Get the value of the Enum
Console.WriteLine(TestEnum.Enum1.ToString("d"));
The special thing you'll see here is we have just mentioned the string formatter "d" and it'll automatically fetch the value of the Enum insteat of printing it's name. So you don't need to do explicit conversion like "(int)TestEnum.Enum1" to get the value.
Get the description value on Enum: In our TestEnum we have provided some description over the Enum. So when required you can fetch the description attribute value if required. The following is the snippet for getting the value of the description attribute using Reflection:
/// <summary>
/// Gets the error message attribute value.
/// </summary>
/// <param name="enumerationType">Type of the enumeration.</param>
/// <returns>
/// value of the attribute
/// </returns>
public static string GetDescriptionOfEnum(this Enum enumerationType)
{
Type type = enumerationType.GetType();
MemberInfo[] memInfo = type.GetMember(enumerationType.ToString());
if (memInfo.Length > 0)
{
object[] attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
return ((DescriptionAttribute)attributes[0]).Description;
}
}
return enumerationType.ToString();
}
This snippet is an extension method that will search for the attribute and if it doesn't find any then it simply returns the name of the enumerationType.
Usage
Console.WriteLine(TestEnum.Enum1.GetDescriptionOfEnum());
Get the Enum from the string name: This is the case where you want to fetch the enum based on the String name provided for that Enum. For example TestEnum.Enum1 is an enum and I want to get this by the string name "Enum1". I've used reflection to get the name compared and return the Enum. Also this snippet will also match the given string with the attribute value on the enum and return the Enum if it matches. Here is the code snippet for that:
public static TestEnum GetEnumByNameOrDescription(string parameterName)
{
var testEnum = TestEnum.Undefined;
foreach (string item in Enum.GetNames(typeof(TestEnum)))
{
testEnum =
string.Equals(item, parameterName, StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(
((TestEnum)Enum.Parse(typeof(TestEnum), item, true)).GetDescriptionOfEnum(),
parameterName, StringComparison.InvariantCultureIgnoreCase)
? (TestEnum)Enum.Parse(typeof(TestEnum), item, true)
: TestEnum.Undefined;
if (testEnum != TestEnum.Undefined)
break;
}
if (testEnum == TestEnum.Undefined)
{
throw new Exception(
string.Format(
"Failed to cast string value {0} " +
"to enum type.",
parameterName));
}
return testEnum;
}
Usage
// get enum by name
var enum1 = Extension.GetEnumByNameOrDescription("Enum1")
// get enum by description
var enum1 = Extension.GetEnumByNameOrDescription("Enumeration 1"))
Get Enum by value
Let's suppose you want to get the Enum by it's value. For example we have Enum2 with the value 2. So if you want to get the Enum2 type by value 2 then you can do that as shown in the following example:
public static TestEnum GetEnumByValue(int value)
{
var testEnum = TestEnum.Undefined;
foreach (int item in Enum.GetValues(typeof(TestEnum)))
{
testEnum = item == value
? (TestEnum)Enum.Parse(typeof(TestEnum), value.ToString("d"), true)
: TestEnum.Undefined;
if(testEnum != TestEnum.Undefined)
break;
}
if (testEnum == TestEnum.Undefined)
{
throw new Exception(
string.Format(
"Failed to cast int value {0} " +
"to enum type.",
value));
}
return testEnum;
}
Usage
var enum2 = Extension.GetEnumByValue(2);
The Extension is a static class I've created to contain these utility methods.
Here's the complete code for the preceding article:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
namespace Demo.EnumOperation
{
/// <summary>
/// The test Enum
/// </summary>
public enum TestEnum
{
[Description("Undefined Enum")]
Undefined = 0,
[Description("Enumeration 1")]
Enum1 = 1,
[Description("Enumeration 2")]
Enum2 = 2,
}
/// <summary>
/// Contains all the extension/utility method
/// </summary>
public static class Extension
{
public static TestEnum GetEnumByValue(int value)
{
var testEnum = TestEnum.Undefined;
foreach (int item in Enum.GetValues(typeof(TestEnum)))
{
testEnum = item == value
? (TestEnum)Enum.Parse(typeof(TestEnum), value.ToString("d"), true)
: TestEnum.Undefined;
if (testEnum != TestEnum.Undefined)
break;
}
if (testEnum == TestEnum.Undefined)
{
throw new Exception(
string.Format(
"Failed to cast int value {0} " +
"to enum type.",
value));
}
return testEnum;
}
public static TestEnum GetEnumByNameOrDescription(string parameterName)
{
var testEnum = TestEnum.Undefined;
foreach (string item in Enum.GetNames(typeof(TestEnum)))
{
testEnum =
string.Equals(item, parameterName, StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(
((TestEnum)Enum.Parse(typeof(TestEnum), item, true)).GetDescriptionOfEnum(),
parameterName, StringComparison.InvariantCultureIgnoreCase)
? (TestEnum)Enum.Parse(typeof(TestEnum), item, true)
: TestEnum.Undefined;
if (testEnum != TestEnum.Undefined)
break;
}
if (testEnum == TestEnum.Undefined)
{
throw new Exception(
string.Format(
"Failed to cast string value {0} " +
"to enum type.",
parameterName));
}
return testEnum;
}
/// <summary>
/// Gets the error message attribute value.
/// </summary>
/// <param name="enumerationType">Type of the enumeration.</param>
/// <returns>
/// value of the attribute
/// </returns>
public static string GetDescriptionOfEnum(this Enum enumerationType)
{
Type type = enumerationType.GetType();
MemberInfo[] memInfo = type.GetMember(enumerationType.ToString());
if (memInfo.Length > 0)
{
object[] attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
return ((DescriptionAttribute)attributes[0]).Description;
}
}
return enumerationType.ToString();
}
}
/// <summary>
/// Main program
/// </summary>
class EnumOperations
{
static void Main(string[] args)
{
var enum2 = Extension.GetEnumByValue(2);
var enum1 = Extension.GetEnumByNameOrDescription("Enum1");
var enumTest1 = Extension.GetEnumByNameOrDescription("Enumeration 1");
Console.WriteLine(Extension.GetEnumByNameOrDescription("Enum1").ToString("d"));
Console.WriteLine(TestEnum.Enum1.ToString("d"));
Console.WriteLine(TestEnum.Enum1.GetDescriptionOfEnum());
Console.ReadKey();
}
}
}