This is your first visit inside The Matrix. Welcome!

The Matrix has you…

This place will take you into the mirage of learning C# programming language, without any previous coding experience being required

Follow the White Rabbit…█

Close
Wednesday, September 20, 2017 16:37

Enumerations

Enumerations are structures which resemble classes but differ from them in that in the enum body we can declare only constants. A variety of logically connected constants can be linked by means of language. These language constructs are the so-called enumerated types.

At concept level, enumerations can be declared using the C# keyword enum, instead of class:

[<modifiers>] enum <enum_name>
{
    constant1 [, constant2 [, [, … [, constantN]]
}

In above blueprint, modifiers can be public, internal and private. Identifier enum_name should follow rules of class naming. Finally, constants are declared inside the body of the enumeration, separated by comas.

Lets take an example of enumeration, the days of the week:

private enum Days
{
    Mon,
    Tue,
    Wed,
    Thu,
    Fri,
    Sat,
    Sun
}

So, you can say that you declared an enumeration of type Days, containing 7 constants named with the names of the days of the week. What you don’t know is the fact that behind the scenes, C# assigns integer values to your enumerations constants. That’s why, the above code is similar to this one:

private enum Days
{
    Mon = 0,
    Tue = 1,
    Wed = 2,
    Thu = 3,
    Fri = 4,
    Sat = 5,
    Sun = 6
}

and we can test it by casting one of the enum members to an integer:

static void Main()
{
    int mondayValue = (int)Days.Mon;
    Console.WriteLine(mondayValue);

    Console.Read();
}

private enum Days
{
    Mon,
    Tue,
    Wed,
    Thu,
    Fri,
    Sat,
    Sun
}

and the output would be 0. However, you cannot say that Days.Mon is of type integer, because it is not, even if it holds an integer value; it is of type Days, as we can check:

static void Main()
{
    Console.WriteLine(Days.Mon is int);
    Console.WriteLine(Days.Mon is Days);

    Console.Read();
}

private enum Days
{
    Mon,
    Tue,
    Wed,
    Thu,
    Fri,
    Sat,
    Sun
}

The C# keyword is is useful for checking the type of a member, returning a boolean value: true if the member is of the type we checked, or false if it’s not. So, our test will display:

enumerations

because Days.Mon is not of type integer, but it is of type Days.

You may wonder why I had to cast Days.Mon to integer, and not display its value like this:

static void Main()
{
    Console.WriteLine(Days.Mon);

    Console.Read();
}

private enum Days
{
    Mon,
    Tue,
    Wed,
    Thu,
    Fri,
    Sat,
    Sun
}

Well, if you run the above example, you will notice the output will not be 0, but Mon!

enum

So, now I can give you the academic definition of enumerations: an enumeration is actually a textual representation of an integer. By default, this number is the constant’s index in the list of constants of a particular enumeration type.

One good thing about enumerations is that we can assign custom values to its constants:

private enum Days
{
    Mon = 13,
    Tue = 205,
    Wed,
    Thu,
    Fri,
    Sat,
    Sun
}

So, we learned what enumerations are, what we can do with them, etc, but how are they actually useful to us? Well, let’s consider a real life example. We have a coffee machine:

public class Program
{
    static void Main()
    {
        Coffee myCoffee = new Coffee();
        Console.Read();
    }
}

public class Coffee
{    
    public Coffee()
    {

    }
}

Wonderful! We just ordered a coffee! But what if we want to specify the size of our coffee? Of course, we can use a property, and set it in the constructor:

public class Program
{
    static void Main()
    {
        Coffee myCoffee = new Coffee(150);
        Console.Read();
    }
}

public class Coffee
{
    private int quantity = 100;
    
    public int CoffeeSize
    {
        get { return this.quantity; }
        set { this.quantity = value; }
    }

    public Coffee(int _quantity)
    {
        this.quantity = _quantity;
    }
}

Above code works perfectly, with only one problem: the users can set whatever value they want, say 1056 ml. Sure, we can do some if-else checks in the property, sure, we can throw some errors, but that is not a very elegant solution, specially if there are a lot of cases. We could also make our quantity variable a constant, but that would also not do us any good, since we would be unable to specify the quantity we want.

And here is where enumerations come to save the day. Lets create an enumeration of the available quantities:

public enum CoffeeSize
{
    Expresso = 100, 
    Normal = 150, 
    Double = 300
}

Starting to see the beauty of it? Since we said that enumerations only hold constants, the values we set to them will be the only values available to the users, and they will not be able to change them. This is exactly what we needed. So, how do we use this enumeration in our example? At the beginning of this lesson, I said that enumerations resemble classes, with the difference that they can only contain constant fields. This also means that we use enumerations the same way we use classes: using instantiation or fields/properties.

public enum CoffeeSize
{
    Expresso = 100, 
    Normal = 150, 
    Double = 300
}

public class Coffee
{
    public CoffeeSize quantity;

    public CoffeeSize Size
    {
        get { return quantity; }
    }

    public Coffee(CoffeeSize size)
    {
        this.quantity = size;
    }
}

The code is rather easy to understand: we declared an enumeration called CoffeeSize, then inside our Coffee class, we declare a field and a property, both of type CoffeeSize. Finally, we set the field in the constructor of the class too. So, now we can have this kind of coffee ordering:

class Program
{
    static void Main()
    {
            Coffee normalCoffee = new Coffee(CoffeeSize.Normal);
            Coffee doubleCoffee = new Coffee(CoffeeSize.Double);

            Console.WriteLine("The {0} coffee is {1} ml.", normalCoffee.Size, (int)normalCoffee.Size);
            Console.WriteLine("The {0} coffee is {1} ml.", doubleCoffee.Size, (int)doubleCoffee.Size);

            Console.Read();
    }
}

public enum CoffeeSize
{
    Expresso = 100, 
    Normal = 150, 
    Double = 300
}

public class Coffee
{
    public CoffeeSize quantity;

    public CoffeeSize Size
    {
        get { return this.quantity; }
    }

    public Coffee(CoffeeSize size)
    {
        this.quantity = size;
    }
}

enum implementation

This is exactly what we wanted in the first place, being able to chose from a predefined set of constant values. And, yes, we cannot change the values of enum members, after declaring them:

class Program
{
    static void Main()
    {
            CoffeeSize.Expresso = 500;

            Console.Read();
    }
}

public enum CoffeeSize
{
    Expresso = 100, 
    Normal = 150, 
    Double = 300
}

because we would get an error: The left-hand side of an assignment must be a variable, property or indexer.

 

EXERCISES
1. Create an enumeration BatteryType, which contains the values for type of the battery (Li-Ion, NiMH, NiCd, …) and use it as a new field for the class Battery.

Solution


Guidelines: Use enum for the type of battery. Search in Internet for other types of batteries.

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            BatteryType myBattery = new BatteryType();
            myBattery = BatteryType.NiCd;

            Console.Read();
        }
    }

    public enum BatteryType
    {
        LiIon,
        NiMH,
        NiCd
    }
}

Comments

comments

Tags: , , , ,

Leave a Reply