FrostyStraw
FrostyStraw

Reputation: 1656

Confusion about return value of Enum.GetValues()

I am reading about enumerations in a book, and the following code example was given:

namespace FunWithEnums
{
    enum EmpType : byte
    {
        Manager = 10, 
        Grunt = 1,
        Contractor = 100,
        VicePresident = 9

    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("**** Fun with Enums *****");

            EmpType emp = EmpType.Contractor;
            EvaluateEnum(emp);
            Console.ReadLine();
        }

        static void EvaluateEnum(System.Enum e)
        {
            Array enumData = Enum.GetValues(e.GetType());

            for (int i =0; i < enumData.Length; i++)
            {
                Console.WriteLine("Name: {0}, Value: {0:D}", enumData.GetValue(i));
            }
            Console.WriteLine();
        }
}

I'm very confused as to what is being printed out in the forloop. The output is

Name: Grunt, Value: 1

Name: VicePresident, Value: 9

Name: Manager, Value: 10

Name: Contractor, Value: 100

But how does it get both the name AND the value of each enumerated element? According to the Microsoft documentation, Array enumData = Enum.GetValues(e.GetType()); should only return " an array of the values of the constants in a specified enumeration." I assume that by constants, it is referring to "Manager", "Grunt", "Contractor", "VicePresident", as opposed to 10, 1, 100 and 9. So why is it returning each pair instead of just the name of the employee type? Also, the output of the following code Console.WriteLine(enumData.GetValue(1)); returns just one value, which is "VicePresident" and doesn't return the number 9 like it does in the forloop. Why is this?

Upvotes: 0

Views: 1044

Answers (4)

rory.ap
rory.ap

Reputation: 35280

Console.WriteLine(String, Object) uses the "Composite Formatting" features of .NET, and when you provide it an enum value, it applies the "Enumeration Format Strings":

G or g

Displays the enumeration entry as a string value, if possible, and otherwise displays the integer value of the current instance.

Thus you can embed {0:G} in your string to substitute the enum name. Although not mentioned, {0:G} is equivalent to {0}, which is what you have observed in your example with Console.WriteLine("Name: {0},....

D or d

Displays the enumeration entry as an integer value in the shortest representation possible.

Thus you can embed {0:D} in your string to substitute the enum value.

Upvotes: 5

JDavila
JDavila

Reputation: 449

The values are being printed out by the given formatting. Try removing the {0:D}, and only use {0}. As in the list that is created, the type is specified for the list in:

        Array enumData = Enum.GetValues(e.GetType());

Upvotes: 0

user4843530
user4843530

Reputation:

GetValue returns an enumeration value object. This object is of a class (Enum class) that will cast to a string with its name, or cast to an integer with its value. So when the string formatting expects a string, it gets that. When it asks for a decimal (Format specifier D), the enum value gives it the default underlying value which is Int32, which easily casts to a Decimal.

Upvotes: 2

Jamiec
Jamiec

Reputation: 136114

The code is explicitly printing the value twice

Console.WriteLine("Name: {0}, Value: {0:D}", enumData.GetValue(i));

The first {0} just print the raw value, the second has a formatting specified (D)

Upvotes: 0

Related Questions