#465 – Dumping All Names and Values for an Enumerated Type

You can use the Enum.GetValues method to iterate through all values of an enumerated type.  You can use this method to dump out the name and value of each enumeration value in the enumerated type.

        public enum Moods
        {
            NOMOOD = 0,
            Ambivalent = 1,
            Crabby = 10,
            Grouchy = Crabby - 1,
            Happy = 42,
            SuperHappy = 2 * Happy
        }
foreach (Moods mood in Enum.GetValues(typeof(Moods)))
    Console.WriteLine("{0} - {1}", mood, (int)mood);

Advertisement

#464 – Getting an Enumeration’s Underlying Type at Runtime

You can use the Enum.GetUnderlyingType static method to find out what the underlying type is that is being used to store an enumerated type’s enumerated values.

        public enum Moods : byte
        {
            NOMOOD = 0,
            Ambivalent = 1,
            Crabby = 10,
            Grouchy = Crabby - 1,
            Happy = 42,
            SuperHappy = 2 * Happy
        }

        static void Main()
        {
            Type moodStorageType = Enum.GetUnderlyingType(typeof(Moods));
            var min = moodStorageType.GetField("MinValue").GetValue(null);
            var max = moodStorageType.GetField("MaxValue").GetValue(null);

            Console.WriteLine("Underlying type for Moods is: {0}", moodStorageType.FullName);
            Console.WriteLine("Values can range from {0} to {1}", min, max);
        }

#463 – Enumerated Values Can Be Any Constant Expression

When you define an enum, the individual values can be implicitly defined (one greater than the previous value), assigned to a constant, or assigned to any constant expression.

In the definition of the Moods enumerated type below, constant expressions are used for some of the values.

        public const int HappyFactor = 42;

        public enum Moods
        {
            NOMOOD = 0,
            Ambivalent = 1,
            Crabby = 10,
            Grouchy = Crabby - 1,
            Happy = HappyFactor,
            SuperHappy = 2 * Happy
        }

#462 – Duplicate Enumerators in an Enumerated Type

When defining a new enumerated type, you can define multiple enumerators that have the same underlying value.  You might do this when you have a finite set of enumerated values and you want to map them to a smaller finite set of internal values.

In the example below, we have six different MovieRatings values, internally.  But we define 10 different enumerators for the type, so some of them end up mapping to the same value.

        public enum MovieRatings
        {
            DidntSeeIt = 0,
            NONE = 0,
            Crappy = 1,
            Horrible = 1,
            Watchable = 2,
            Average = 3,
            Good = 4,
            SeeIt = 4,
            Great = 5,
            MustSee = 5
        };

Happy Thanksgiving

Happy Thanksgiving (in the United States)!  There will be no C# post today, but we’ll resume regular posts tomorrow.

#461 – Enumeration Elements Don’t Need to Be Sequential

Enumeration elements are implicitly set to consecutive integers, starting at 0, as indicated in the comments below.

        // Default type is int
        public enum Mood
        {
            Crabby,      // 0
            Happy,       // 1
            Petulant,    // 2
            Elated       // 3
        };

You can also assign any values you like to the constants.

        public enum Mood
        {
            Crabby = -50,
            Happy = 80,
            Petulant = -20,
            Elated = 99
        };

You can define these constants in any order. They don’t have to be sequential.

        public enum Days
        {
            Friday = 5,
            Monday = 1,
            Saturday = 6,
            Sunday = 0,
            Thursday = 4,
            Tuesday = 2,
            Wednesday = 3
        };

#460 – Converting from a String to an Enum Type

You can convert a string to the corresponding enumerator in an enum type by using the Enum.Parse method.  This is a static method that takes the specific enumerated type and a string value and returns the corresponding enumerated value of the type.

        public enum Mood { Crabby, Happy, Petulant, Elated };

        static void Main()
        {
            string myMood = "elated";
            Mood mood = (Mood)Enum.Parse(typeof(Mood), myMood, true);

        }

The third parameter indicates whether case should be ignored when searching for a value.

Because Enum.Parse returns a value of type object, you need to cast the return value to the desired enumerated type.

If an enumerator in the enum type that matches the specified string value can’t be found, the method will throw an ArgumentException.

#459 – Assigning a Value of a Different Type to an enum

You can convert to an enum value from its underlying type by casting the underlying type (e.g. int) to the enum type.  You can also assign a value of a different type, one that does not match the underlying type, as long as the cast succeeds.

        // By default stored as int, with values 0,1,2,3
        public enum Mood { Crabby, Happy, Petulant, Elated };

        static void Main()
        {
            byte moodValue = 3;
            Mood mood;

            // Works (byte -> int)
            mood = (Mood)moodValue;

            // Also works, since cast converts value to 2 (Petulant)
            double moodValue2 = 2.1;
            mood = (Mood)moodValue2;
        }

#458 – Errors While Converting Between enum and Underlying Type

You can convert to an enum value from its underlying type by casting the underlying type (e.g. int) to the enum type.

However, when you cast a value that doesn’t have a corresponding enumerator in the type, you don’t get any sort of error.

In the example below, the Mood type has enumerators that take on the values (0,1,2,3).  But we can successfully cast a value of 4 to the Mood type.

        public enum Mood { Crabby, Happy, Petulant, Elated };

        static void Main()
        {
            int moodValue = 4;
            Mood mood;

            mood = (Mood)moodValue;
            Console.WriteLine(mood);   // 4

To detect this problem, you can check to see if the value is defined in the enumerated type using the Enum.IsDefined method.

            if (Enum.IsDefined(typeof(Mood), moodValue))
                mood = (Mood)moodValue;
            else
                Console.WriteLine("{0} is not a valid Mood value!", moodValue);

#457 – Converting Between enums and their Underlying Type

When you declare an enum, by default each enumerated value is represented internally with an int.  (System.Int32 – 4 bytes).  You can convert between values of the underlying type and enum values using an explicit cast.  Because an enum is represented by an int by default, you can convert between integers and enum values.

            Mood m = (Mood)2;
            Console.WriteLine(m);   // Petulant

            m = Mood.Crabby;
            int i = (int)m;
            Console.WriteLine(i);   // 0