Enum.IsDefined with flagged enums
Asked Answered
Y

2

9

I'm currently reading the book C# 4.0 in a Nutshell, which by the way I think is an excellent book, even for advanced programmers to use as a good reference.

I was looking back on the chapters about the basics, and I came across a trick to tell if a certain value is defined in an Enum when using flagged enums.
The book states that using Enum.IsDefined doesn't work on flagged enums, and suggests a work-around like this :

static bool IsFlagDefined(Enum e)
{
    decimal d;
    return (!decimal.TryParse(e.ToString(), out d);
}

This should return true if a certain value is defined in an enum which is flagged.

Can someone please explain to me why this works ?

Thanks in advance :)

Yingyingkow answered 9/2, 2011 at 20:21 Comment(1)
as an aside theres another case where Enum.IsDefined might behave different from expected (or maybe that's default(T)). Enum.IsDefined(default(T)) can return both true and false. default(T) (where T is an enum) always returns (T)0 so if T does not have a valid value for (T)0 the result is false. Have trhown me off at least oncePhila
P
13

Basically, calling ToString on any enum value of a type declared with the [Flags] attribute will return something like this for any defined value:

SomeValue, SomeOtherValue

On the other hand, if the value is not defined within the enum type, then ToString will simply produce a string representation of that value's integer value, e.g.:

5

So what this means is that if you can parse the output of ToString as a number (not sure why the author chose decimal), it isn't defined within the type.

Here's an illustration:

[Flags]
enum SomeEnum
{
    SomeValue = 1,
    SomeOtherValue = 2,
    SomeFinalValue = 4
}

public class Program
{
    public static void Main()
    {
        // This is defined.
        SomeEnum x = SomeEnum.SomeOtherValue | SomeEnum.SomeFinalValue;

        Console.WriteLine(x);

        // This is not (no bitwise combination of 1, 2, and 4 will produce 8).
        x = (SomeEnum)8;

        Console.WriteLine(x);
    }
}

The output of the above program is:

SomeOtherValue, SomeFinalValue
8

So you can see how the suggested method works.

Picoline answered 9/2, 2011 at 20:26 Comment(3)
Should SomeEnum.SomeValue = 0?Earthy
@PaulB: It can be. Are you asking because typically there is a None value for 0? That is true and probably less confusing. Maybe I'll update the answer just so as not to throw anyone off.Picoline
Yes - just that you couldn't represent SomeValue with any of the others... Thanks for changing :)Earthy
U
0

If the value of e isn't can't be created using a combination of flags ToString() defaults to an integral number. And integral numbers will of course parse as decimal.

But why your code parses as decimal isn't entirely clear to me. But probably integral types won't work for both enums that are based in Int64 and UInt64.

Unwilled answered 9/2, 2011 at 20:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.