Search code examples
c#enumsenumerationenum-flags

What is the difference between local defined Enum-flags and Enum-defined flags?


I was working with Enums and I was looking for a way to group a range of enum-values to separate groups when I came across [Flags] for Enums.

I noticed that the example on ms-Docs was printing the array of the local declared enum bit-wise range (as the enum names) but not when I declared the same range in the enum itself.

I have tested the Enum.HasFlag() and it does the same calculation, but it does not print it in the same way. I have found plenty of solutions for flag iterators, but it seems that the feature is there already for local declared variables.

What is the difference between the enum declared value and the local declared enum?

[Flags] 
public enum DinnerItems
{
        None = 0,
        Entree = 1,
        Appetizer = 2,
        Side = 4,
        Dessert = 8,
        Beverage = 16,
        BarBeverage = 32,
        MyOrder = Appetizer | Entree | Beverage | Dessert,
}

 DinnerItems flagValue = DinnerItems.None | DinnerItems.Side;

            DinnerItems myOrder = DinnerItems.Appetizer | DinnerItems.Entree |
                                 DinnerItems.Beverage | DinnerItems.Dessert;

            Console.WriteLine("{0} includes {1}: {2}",
                            myOrder, flagValue, myOrder.HasFlag(flagValue));

This will print: MyOrder includes Side: False

Same code when removing DinnerItems.MyOrder from Enum: Entree, Appetizer, Dessert, Beverage includes Side: False


Solution

  • As per the docs:

    The return value is formatted with the general format specifier ("G"). That is, if the FlagsAttribute is not applied to this enumerated type and there is a named constant equal to the value of this instance, then the return value is a string containing the name of the constant. If the FlagsAttribute is applied and there is a combination of one or more named constants equal to the value of this instance, then the return value is a string containing a delimiter-separated list of the names of the constants.

    Without MyOrder, it thus does the delimiter-separated list of the names - which appears to be what you want.

    But with MyOrder - well now MyOrder is the simplest combination of one or more named constants (one constant, vs four) - so it outputs MyOrder instead.