hardywang
hardywang

Reputation: 5172

Generic Enum parser with some exception rule

Let's say I have an enum like

enum A
{
    AA,
    BB,
    CC,
    DD
}

I want to parse string values into Enum types, like "abc" -> AA, "BB" -> BB, "CC" -> CC, "DD" -> DD, as you can see AA has some special rule for the translation. So in this case Enum.TryParse<A>("abc", true, out AEnum) would not serve the purpose. I can write some special codes to handle this exception value, and rest of values fall to use generic enum parser.

I have several enums with such exception rules, but if I come up with this type of codes

    public static T GetEnumValue<T>(this string stringValue) where T : struct, IComparable, IConvertible, IFormattable
    {
        if (typeof(T).IsEnum)
        {
            if (typeof(T) == typeof(A))
            {
                T myEnum;
                if (Enum.TryParse<T>(stringValue, true, out myEnum))
                {
                    return myEnum;
                }
                else
                {
                    // handle some special cases.
                    if (string.Compare(stringValue, "abc", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return A.AA;
                    }
                }
            }

            return default(T);
        }
        else
        {
            throw new Exception();
        }
    }

The code would not even compile, because compiler complains return value of that special case.

I strictly don't want to have attribute on my enum for some reason.

Anyone has good idea?

Upvotes: 1

Views: 94

Answers (3)

Tim S.
Tim S.

Reputation: 56556

You could use Json.NET as your parser. With EnumMember, you can specify the exceptions to the rule. By default, it is case insensitive.

void Main()
{
    Console.WriteLine("abc".GetEnumValue<A>()); // AA
    Console.WriteLine("ABC".GetEnumValue<A>()); // AA
    Console.WriteLine("AA".GetEnumValue<A>());  // AA
    Console.WriteLine("Bb".GetEnumValue<A>());  // BB
}

[JsonConverter(typeof(StringEnumConverter))]
enum A
{
    [EnumMember(Value = "abc")]
    AA,
    BB,
    CC,
    DD
}
public static class Ext
{
    public static T GetEnumValue<T>(this string stringValue)
            where T : struct, IComparable, IConvertible, IFormattable
    {
        return JsonConvert.DeserializeObject<T>('"' + stringValue + '"');
    }
}

Upvotes: 0

Ulugbek Umirov
Ulugbek Umirov

Reputation: 12807

Replace the following code:

if (string.Compare(stringValue, "abc", StringComparison.OrdinalIgnoreCase) == 0)
{
    return A.AA;
}

by

if (string.Compare(stringValue, "abc", StringComparison.OrdinalIgnoreCase) == 0)
{
    return (T)Enum.Parse(typeof(T), "AA");
}

Upvotes: 1

dvlsg
dvlsg

Reputation: 5538

The following line is ugly, but I believe will technically work for those special exceptions.

return (T)(object)A.AA;

Upvotes: 1

Related Questions