2

I have enums in one of my windows application like below:

private enum ModificationType
{
    Insert = 0,
    Update = 1,
    Delete = 2
}

I have below function:

private void UpdateDatabaseTransactions(ModificationType _modifcationType)
        {
int modType = (int)_modifcationType;
if (modType == 0) {...}
if (modType == 1) {...}
if (modType == 2) {...}

also I can use it like below:

if (_modifcationType == ModificationType.Insert) {...}
if (_modifcationType == ModificationType.Update) {...}
if (_modifcationType == ModificationType.Delete) {...}
}

What is the difference between the both and in which scenarios I have to typecast the value and use, is there any performance boosters in using any one of the above, or both are same?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Abbas
  • 4,948
  • 31
  • 95
  • 161

7 Answers7

6

What happens when you decide to change the ModificationType enum later? For example:

private enum ModificationType
{
    Insert = 0,

    /* Oops, need a special insert type here */
    InsertSpecial = 1,

    Update = 2,
    Delete = 3
}

This is, admittedly, a contrived example. (But certainly not impossible - assume your enum is used to reference some external dependency that introduces a breaking change, say a C API.)

But if you refer to these enum types by value, you'll have to track down all references of them. Do you want to go trawling through your code trying to figure out if the number 3 is used to reference that enum or some other random constant?

Instead, you should use ModificationType.Delete so that you don't have to worry about these issues. That's why the enum type exists, after all.

There is no performance penalty for using ModificationType.Delete instead of 4, 5, 6 or whatever it might happen to be.

Edward Thomson
  • 74,857
  • 14
  • 158
  • 187
4

The scenario I could only imagine you need to cast (from) if you read _modifcationType from outside your code - ie: from file, database, JSON, etc.

Other than that - I'd use it without casting - esspecially in a switch..case block.

YS.
  • 1,808
  • 1
  • 19
  • 33
  • i came accross an answer on SO, by @johnny g, who says never use without casting case in switch, you can refer his answer here: http://stackoverflow.com/questions/1758321/casting-ints-to-enums-in-c-sharp, he says "Not sure about why, but I recently found this "feature" incredibly useful. I wrote something like this the other day" – Abbas Mar 05 '12 at 19:54
3

When comparing an enum instance to a specific value you should always use the named enum values. Using ModificationType.Insert is much more edit / change safe than 0. An edit of a value won't affect existing comparisons using ModificationType.Insert but will silently cause the behavior of functions relying on it to be 0.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
3

They're both nearly equivalent (assuming the integer values you're using actually match up to the values you're using in your enum). You're not going to notice a performance difference between the two.

That being said, you should use the actual Enum values when possible. The whole point of using an Enum is to give meaningful values to the integers. If somebody new to the codebase looks at the first example, they're not going to know what the code is doing. If they look at the second, it will actually still be meaningful.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
3

Both samples should run the same. I would suggest using the second one though, because of readability. It is much easier to understand and maintain than the first one.

Msonic
  • 1,456
  • 15
  • 25
1

Second half: You may need to cast from enum if you do math operations on values, also it is rare as enums are automatically casted to corresponding integer type.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
1

Use the enum values. A named enum value, like your ModificationType.Delete is a compile-time constant.

Unless you have need to do otherwise:

  • Have the default value of the enum (0) undefined, or define is as Unknown or something similar:

    public enum ModificationType
    {
     [ Unknown = 0 , ]
     Insert = 1 ,
     Update = 2 ,
     Delete = 3 ,
    }
    
  • When you do something with them like your if/then statements, use a switch and throw an InvalidOperationException or similar exception for out-of-range values. This will save your bacon (or someone else's) down the line when domain of the enum expands, or you have a bug where an enum instance isn't properly initialized to a correct value:

    switch ( someModificationType )
    {
    case ModificationType.Insert : performInsert() ; break ;
    case ModificationType.Delete : performDelete() ; break ;
    case ModificationType.Update : performUpdate() ; break ;
    default :
      throw new InvalidOperationException() ;
      break ;
    }
    

One of my favorite MS Word bugs was doing something in word and encountering a popup MessageBox with an OK button and the cryptic message: "This message should never appear". Not exactly useful, but the developer's heart was in the right place.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135