简体   繁体   中英

Friendly Enum Strings With Flags Attribute

After perusing some other questions regarding common ways to generically create access to friendly strings for enumeration values in C# this answer appeared to be my best bet for a generic solution where the friendly strings can be placed in the definition of the enumeration using DescriptionAttribute s.

I implemented this as an extension method, but quickly realized that it would only work for standard enums, where the [Flags] attribute is not specified. I'm not completely sure of the best way to pursue implementing this for cases where the attribute is present.

Since the flags attribute means that multiple values can be selected simultaneously, using a single "friendly string" would not make sense. I was thinking of defining the friendly strings in the same way, but overloading the extension method to take that specific enum type where it would return a List<string> to provide friendly strings for all of the selected values.

The solution described above would work, but I feel like there will be lots of code duplication since each enum that uses the Flags attribute will require it's own extension method because enums can only be inherited by System.Enum , eliminating my ability to create a base type. It would be nicer if I could have a more generic method that can handle this by checking the enum if the flags attribute is present and then return one of the following:

  • single string (if no Flags), list (if Flags) - signature returns object
  • single string (if no Flags), list (if Flags) - signature returns dynamic
  • list that may only contain one value if flags is not specified - signature returns List<string>

I feel like this question may be a case of "having my cake and eating it too", since I would prefer to not have to do additional checks after getting the friendly string(s) and deduping my code. Is there a trick or good way to do this that isn't a messy hack?

You can write a method just as in the answer you link, but with support for flag enums, and return a comma seperated string, something like:

public static string GetDescription(Enum value)
{
    Type type = value.GetType();
    var values = Enum.GetValues(type);
    var setValues = new List<Enum>();
    foreach(var enumValue in values)
    {
        if (value.HasFlag((Enum)enumValue))
            setValues.Add((Enum)enumValue);
    }
    var stringList = new List<string>();
    foreach (var singleValue in setValues)
    {
        var name = Enum.GetName(type, singleValue);
        if (name != null)
        {
            FieldInfo field = type.GetField(name);
            if (field != null)
            {
                DescriptionAttribute attr =
                       Attribute.GetCustomAttribute(field,
                         typeof(DescriptionAttribute)) as DescriptionAttribute;
                if (attr != null)
                {
                    stringList.Add(attr.Description);
                }
            }
        }
    }
    return string.Join(",", stringList.ToArray());
}

not the cleanest code, but you get the idea, only keep in my mind, that it wont work as expected for enums that are not flags - just throwing an idea.

Use enum.ToString() to get "unfriendly" strings (where enum is your Enum variable). Write a reusable extension method to convert UnfriendlyString to a friendly "unfriendly string" (eg insert space-lowercase wherever there is an uppercase or something similar).

For [Flags] you could either Split the unfriendly string, convert each sub-string, and perhaps Join again; or your extension method could take the commas into account.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM