15

Until asking a question on here I never considered (enums) to be a "bad thing." For those out there that consider them not to be best practice, what are some approachs/patterns for avoiding their use in code?

Edit:

public Enum SomeStatus
 Approved = 1
 Denied = 2
 Pending =3
end Enum
Community
  • 1
  • 1
Achilles
  • 11,165
  • 9
  • 62
  • 113
  • 7
    Ummm... strongly typed enumerations are a good thing? (yes) – Ed S. Feb 15 '10 at 19:45
  • Just to clarify, by 'enumeration' you mean enumerated types, not the use of the IEnumerable interface to represent a sequence. – Eric Lippert Feb 15 '10 at 19:46
  • 1
    I was told that they creating coupling and dependencies between classes... – Achilles Feb 15 '10 at 19:46
  • 2
    I think your question is too vague. Enumerated types, like pretty much every other programming concept, have good and bad uses. They are a bad thing for some situations and a good thing for others. Can you be more specific? – Jeff Yates Feb 15 '10 at 19:50
  • I wonder if this is something people in the SOLID community might elaborate upon? – Achilles Feb 15 '10 at 20:01

5 Answers5

34

The problem with enums is described in Fowler's Refactoring, where it is considered a code smell. It has nothing to do with type safety, but rather that it forces you to sprinkle switch statements all over your code, thus violating the DRY Principle.

The State pattern is a better model of the same structure because it lets you implement and vary the logic related to the same state in the same class. This also increases cohesion and lessens class coupling.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
12

I think using an enum is a good thing. It provides strong type safety.

They have some disadvantages at times, but this is really typically related to situations where every possible option is not known in advance. If you have a fixed set of options, such as your example, then strong typed enums are a good thing, and should not be avoided.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Infact they should be used in this case, instead of hard coded 1, 2 and 3 everywhere. – PostMan Feb 15 '10 at 19:53
  • Yes, the provide a level of safety and understanding you wouldn't get using "magic numbers". – Reed Copsey Feb 15 '10 at 19:54
  • 3
    But beware they don't actually provide type safety other than enforcing that the value be of the type of the enum's underlying type. `status = (SomeStatus)8374` will compile and run just fine, but probably break your code. – Kent Boogaart Feb 15 '10 at 20:26
  • 1
    @Kent: Very true, but it's still safer than just using a number, since (without a cast) the compiler will do some checking. Much more maintainable, too, since the intent is clear by the name. – Reed Copsey Feb 15 '10 at 20:27
  • -1 The are no fixed sets of options. There will be someone needing another status like **Archived** or **Closed** or **Planned**, and there will be someone who wants **Archived** having some different behaviors from others etc. – onof Jan 24 '12 at 07:23
  • 1
    @onof This completely depends on the application in question. With many systems, there are fixed sets of options. – Reed Copsey Jan 24 '12 at 18:57
  • I am fup using ENUMs at this moment,because I am referencing it to 300 projects and it seems I have to build 300 projects again and to put those 300 DLL again in production.phew!! (because I've added one new value in ENUM) – Dirty Developer Apr 01 '17 at 06:34
7

I like turtles class enums.

Arnis Lapsa
  • 45,880
  • 29
  • 115
  • 195
2

I like enums for putting easy-to-use-and-understand names on related sets of values. I just don't like the c# implementation. Using your sample enum:

SomeStatus status = 17;

This compiles and runs without complaint, even though 17 is way out of bounds.

Delphi has better enums (or at least, it used to - its been years since I have used it)

Ray
  • 21,485
  • 5
  • 48
  • 64
  • Could you elaborate on "17 is way out of bounds"? – Jace Rhea Feb 15 '10 at 21:51
  • 1
    The values specified in the enumerations are 1, 2, and 3. However, a variable like my example will take any integer value, whether or not it is a valid value within the enum. I think that takes away from the type-safety aspect of enumerations. – Ray Feb 15 '10 at 22:26
  • I don't agree 17 is an invalid enum in all contexts. I believe this is what you are saying, since you didn't like the C# implementation. What if the set of status type values were being defined from an external source and we aren't concerned with the values 4-16 in our app? 17 may be a perfectly valid enum value in this context. In an app I recently worked on we had a large number of enums that made up a language resource, and wanted to group the enum values for code clarity. So we designated groups in hundreds, where maybe only the values 100-157 get used, than skip to 200 for the next group. – Jace Rhea Feb 15 '10 at 22:57
  • 1
    Nothing wrong with that - but in the sample enum in the question, the values were 1, 2, 3. No 17. So 17 is invalid for this application. If 17 were required, then the enum could be declared to include 1,2,3,17. The 17 would be valid, but 16 and 18 (and any other number) would not. IMO, if you need to use values which are not part of the declared enum, then you should not be using an enum. – Ray Feb 15 '10 at 23:14
2

The main point with enumeration is that it is defined in only one place (normalisation in database terms). If this enumeration is legitimately part of the class you are writing, then carry on.

Otherwise, particularly if you find yourself declaring it more than once, rethink what your enumeration is for. Is it actually carrying data? Will there be enough values to consider storing the possibilities in a database?

Phil H
  • 19,928
  • 7
  • 68
  • 105