0

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?

Dan Dumitru
  • 5,348
  • 1
  • 33
  • 43
FrostyStraw
  • 1,628
  • 3
  • 25
  • 34
  • "I assume": That's your problem right there. You made up a story about what "values of the constants" means. The output of your program demonstrates that the story was clearly wrong. So take what you've learned from the output, and try to construct a new story which is consistent with the facts in front of you. – 15ee8f99-57ff-4f92-890c-b56153 Aug 05 '16 at 14:39
  • So when it refers to the "constant", it is referring to the name-value PAIR, not just the name? – FrostyStraw Aug 05 '16 at 14:51
  • 1
    Not a value pair, an object that has methods and member variables and parent classes, and which Console.WriteLine will query for its string representation, when it wants a string, and its numeric representation when it wants that. –  Aug 05 '16 at 14:53
  • @FrostyStraw Right, a .NET enum constant is an object with stuff. It's not like an enum in C. – 15ee8f99-57ff-4f92-890c-b56153 Aug 05 '16 at 14:54

4 Answers4

5

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.

rory.ap
  • 34,009
  • 10
  • 83
  • 174
2

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.

  • So GetValue() returns an object because the array enumData contains OBJECTS thanks to the Enum.GetValues() method that was used to populate the array? – FrostyStraw Aug 05 '16 at 14:43
  • Yes, GetValues gives you an array of the values, each one being Enum class. –  Aug 05 '16 at 14:44
  • On the loop you could do something like foreach (var value in e.getValues()) Console.WriteLine("Name: {0}, Value: {0:D}", value); –  Aug 05 '16 at 14:46
  • Look at the example here: https://msdn.microsoft.com/en-us/library/system.enum.getvalues(v=vs.110).aspx –  Aug 05 '16 at 14:48
  • I found that this answered cleared up the main thing that was confusing me (the actual nature of enum objects) – FrostyStraw Aug 05 '16 at 16:18
  • I also have a few question about the foreach example you posted in your comment. I can't really do e.getValues() in this case because e itself is an Enum object (representing a Contractor).I'd have to do Enum.getValues(e.getType())...This is also because Enum.getValues() is a static method, so it takes in the enumeration type as an argument (instead of being able to use the . operator on an instance of the class). --Is what I just said correct? – FrostyStraw Aug 05 '16 at 16:28
  • 1
    Yes, you are totally right about the correct syntax for that expression. My mistake. –  Aug 05 '16 at 19:04
0

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)

Jamiec
  • 133,658
  • 13
  • 134
  • 193
0

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());
JDavila
  • 409
  • 1
  • 7
  • 22