jdroke
jdroke

Reputation: 27

C# using [Flags] with [Description]

I'm looking to combine the use of enumerations - with the bitwise [Flags] - as well as using a description of the combination of the results. I've looked into examples here using the Flags Attribute, and using the Description Attribute, but not both.

Something like:

[Flags]
public enum ReasonCode
{
    [Description("Verified")]
    None = 0,
    [Description("Check A")]
    Reason1 = 1,
    [Description("Check B")]
    Reason2 = 2,
    [Description("Check C")]
    Reason3 = 4,
    [Description("Check D")]
    Reason4 = 8,
    [Description("Check E")]
    Reason5 = 16,
    [Description("Check F")]
    Reason6 = 32,
    [Description("Check G")]
    Reason7 = 64
}

I need to specify all reasons why there was a failure. Using "Reason1", etc... isn't descriptive enough for what I am looking for. I would need a much more verbose description, like "Reason1 - Check A".

For Example:

A value of 5 would be Reason1 and Reason3.
The description would then be:

Failure:
Reason1 - Check A.
Reason3 - Check C.

Is is possible to do combine descriptions like flags?

Upvotes: 0

Views: 1787

Answers (2)

user3944074
user3944074

Reputation: 21

Here's a more generic extension method that I have used which will deal with all enum values including flag combinations:

public static string GetDescription(this Enum value)
{
    //pull out each value in case of flag enumeration
    var values = value.ToString().Split(',').Select(s => s.Trim());
    var type = value.GetType();

    return string.Join(" | ", values.Select(enumValue => type.GetMember(enumValue)
       .FirstOrDefault()
       ?.GetCustomAttribute<DescriptionAttribute>()
       ?.Description
       ?? enumValue.ToString()));
}

If a description attribute is not present then it will simply return the value itself.

Upvotes: 2

Tommaso Belluzzo
Tommaso Belluzzo

Reputation: 23685

In order to produce the result you are looking for, use the following code:

public static String GetDescription(ReasonCode reasonCode)
{
    if (reasonCode == ReasonCode.None)
        return "Verified";

    StringBuilder sb = new StringBuilder();
    sb.AppendLine("Failed:");

    foreach (ReasonCode rc in Enum.GetValues(typeof(ReasonCode)).Cast<ReasonCode>())
    {
        if (rc == ReasonCode.None)
            continue;

        if (reasonCode.HasFlag(rc))
            sb.AppendLine(rc.ToString() + " - " + GetEnumDescription(rc));
    }

    return sb.ToString();
}

The code used to retrieve the description value is based on this implementation:

public static String GetEnumDescription(Enum value)
{
    String valueText = value.ToString();
    Type type = value.GetType();

    FieldInfo fi = type.GetField(valueText);
    Object[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (attributes.Length > 0)
    {
        DescriptionAttribute attribute = (DescriptionAttribute)attributes[0];
        return attribute.Description;
    }

    return valueText;
}

You can find a working demo here.

Upvotes: 0

Related Questions