Framework Tips X: More on enums

Yes, I know that previous Framework Tips had number VIII, but I didn’t notice that I already had VIII, so this makes this part 10th in the row.

Each enum, is a named collection of flags, that mask a numeric type. For example:

public enum ErrorCodes
{
    FileNotFound = 0x12,
    OutOfDiskSpace = 0x14
}

You could use this enum in an error handling method like:

public void HandleError(ErrorCodes errorCode)
{
    switch(errorCode)
    {
        case ErrorCodes.FileNotFound:
            Console.WriteLine("File not found!");
            break;
        case ErrorCodes.OutOfDiskSpace:
            Console.WriteLine("No disk space left!");
            break;
    }
}

Very simple method, that you can now call from other code, like this:

HandleError(ErrorCodes.FileNotFound);

HandleError method however (as well as ErrorCodes enum, but we’ll get to that in a second) has an issue.

You can call it with code like:

HandleError((ErrorCodes)3);

What now? The cast will succeed (remember that enum is just a mask on an int). You should always put a default clause in such switch, to defend yourself from such malicious input.

 

Now, what will happen if I write:

HandleError(default(ErrorCodes));

What is the default value for ErrorCodes enum? If you keep in mind that ErrorCodes is really an int, the answer is obvious – 0. It is even more obvious, if you notice, that 0 is the only value you don’t have to cast explicitly where ErrorCodes is expected!

HandleError(0); //this will compile
HandleError(5); //this will NOT compile
HandleError((ErrorCodes)5); //this will compile just fine

That’s why it’s always a good idea to have meaningful default value for your enums.

public enum ErrorCodes
{
    NoError = 0,
    FileNotFound = 0x12,
    OutOfDiskSpace = 0x14
}

Technorati Tags: