2 minute read

Enums in C# offer a way to define a set of named constants, making your code more readable and maintainable. However, sometimes enums benefit from additional context, such as descriptions, which can provide clearer information about each enum value. In this blog post, we’ll explore a practical method, ToDescription<T>, that retrieves the description of an enum value, or defaults to the enum name if no description is provided.

Introducing the ToDescription<T> Method

The ToDescription<T> method allows you to extract the DescriptionAttribute from an enum value if it has been defined. This can be particularly useful for displaying user-friendly names in your UI or logging systems. Here’s a detailed look at how this method works:

/// <summary>
/// Retrieves the description of an enum value if a <see cref="DescriptionAttribute"/> is defined.
/// If no description is found, returns the enum name instead.
/// </summary>
/// <typeparam name="T">Enum type to look in</typeparam>
/// <param name="value">Enum value</param>
/// <returns>Description or enum name</returns>
public static string ToDescription<T>(T value) where T : struct
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("T must be an enum type", nameof(value));
    }

    var fieldName = Enum.GetName(typeof(T), value);
    if (fieldName == null)
    {
        return string.Empty;
    }

    var fieldInfo = typeof(T).GetField(fieldName,
        BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static);
    if (fieldInfo == null)
    {
        return string.Empty;
    }

    var descriptionAttribute =
        (DescriptionAttribute)fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false)
            .FirstOrDefault();
    return descriptionAttribute == null ? fieldInfo.Name : descriptionAttribute.Description;
}

Breakdown of the Method

  1. Type Constraint:
    • The method uses a generic type parameter <T> constrained to struct to ensure it operates only with value types. It specifically checks if T is an enum.
  2. Enum Type Validation:
    • if (!typeof(T).IsEnum): Ensures that the method is only used with enum types. If T is not an enum, an ArgumentException is thrown, providing clear feedback about the incorrect usage.
  3. Retrieve Field Name:
    • var fieldName = Enum.GetName(typeof(T), value);: Fetches the name of the enum field that corresponds to the provided value.
  4. Get Field Information:
    • var fieldInfo = typeof(T).GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static);: Uses reflection to obtain metadata about the enum field.
  5. Extract Description Attribute:
    • var descriptionAttribute = (DescriptionAttribute)fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault();: Retrieves the DescriptionAttribute if it exists. If no description attribute is found, it defaults to the enum name.
  6. Return Value:
    • The method returns the description if it is available. If the description attribute is not defined, it falls back to returning the enum name.

Practical Example

Consider the following enum with descriptions:

public enum Status
{
    [Description("Operation completed successfully.")]
    Success,

    [Description("An error occurred during the operation.")]
    Error,

    [Description("The operation is still pending.")]
    Pending
}

You can use the ToDescription method as follows:

public class Program
{
    public static void Main()
    {
        var status = Status.Error;
        Console.WriteLine(status.ToDescription()); // Output: An error occurred during the operation.
    }
}

In this example, ToDescription provides a descriptive string for the Status.Error enum value, enhancing readability and clarity.

Conclusion

The ToDescription<T> method is a valuable addition to any C# project that utilizes enums. By retrieving and displaying descriptions associated with enum values, you enhance the usability and maintainability of your code. This approach leverages reflection to dynamically access enum metadata, making your application more adaptable and user-friendly. Implementing this method ensures that your enums are not only functional but also informative, providing a better experience for both developers and users.

Leave a comment

Your email address will not be published. Required fields are marked *

Loading...