Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A way to parse .NET enum string or int value attributed with 'Flags'

There is a nice way of figuring out the enumeration element using the following approach:

// memberType is enum type
if (Enum.IsDefined(memberType, valueString))
{
    return Enum.Parse(memberType, valueString);
}
else
{
    try 
    {
        var underlyingValue = Convert.ChangeType(valueString, Enum.GetUnderlyingType(memberType));
        if (Enum.IsDefined(memberType, underlyingValue))
        {
            return underlyingValue;
        }
    }
    catch...
}

This works like charm. Except for values built from enumerations marked with FlagsAttribute. For example, for this enum and a value:

[Flags]
enum MyEnum {
    One = 0x1,
    Two = One << 1,
    Four = One << 2,
    Eight = One << 3
}

var e = MyEnum.One | MyEnum.Eight;

the approach above doesn't work. Looks like the only way to make it work is to try to get all the enum values and bitwise AND them with the input value. That's somewhat tedious though. So do you know any better way?

Answer:

The final method looks like this:

var parsed = Enum.Parse(memberType, valueString);
decimal d;
if (!decimal.TryParse(parsed.ToString(), out d))
{
    return parsed;
}
throw new ArgumentOutOfRangeException(memberInfo.Name, valueString, "Bad configuration parameter value.");
like image 688
Schultz9999 Avatar asked Apr 26 '11 19:04

Schultz9999


2 Answers

I guess a better question to ask, how to detect bad values.

Looks like there is a nice work around found in C# 4.0 in a Nutshell. From here. Once you Parse the integer value to the enum, you can use this and see if the value is valid. This will work for combined flags.

static bool IsFlagDefined(Enum e)
{
    decimal d;
    return !decimal.TryParse(e.ToString(), out d);
}
like image 119
SwDevMan81 Avatar answered Nov 07 '22 07:11

SwDevMan81


This is expected behavior, as you can get values that do not correspond to the flags. For example, let's assume value a = 1, b = 2, c = 4, d= 8, etc. (Just standard binary progression). It is possible to have a 5 for the value (a & c) or 7 (a, b & c).

like image 33
Gregory A Beamer Avatar answered Nov 07 '22 06:11

Gregory A Beamer