Friday, February 23, 2007

Defining values in enums

I got caught out earlier with something not working as I expected. It may well be documented behaviour somewhere, but I've not been able to find anything specifically mentioning it following a brief search, so I thought I'd document it.

In an attempt to follow the guidelines for declaring an enum, specifically, placing the values in alphabetical order and providing a default "zero value", I came up with the following:


public enum Decision {
  Accept,
  Error,
  Reject,
  Unknown = 0
}



Unfortunately this leads to the following values being assigned:
Accept = 0
Error = 1
Reject = 2
Unknown = 0

and thus Accept and Unknown become one and the same.

Make sure that any that are declared with a value go above any that aren't!

5 comments:

rajbk said...

http://msdn2.microsoft.com/en-us/library/aa664599(VS.71).aspx

If the declaration of the enum member has a constant-expression initializer, the value of that constant expression, implicitly converted to the underlying type of the enum, is the associated value of the enum member.
If the declaration of the enum member has no initializer, its associated value is set implicitly, as follows:

* If the enum member is the first enum member declared in the enum type, its associated value is zero.
* Otherwise, the associated value of the enum member is obtained by increasing the associated value of the textually preceding enum member by one. This increased value must be within the range of values that can be represented by the underlying type; otherwise, a compile-time error occurs.

rajbk said...

This is the best guideline to follow

http://blogs.msdn.com/kcwalina/archive/2004/05/18/134208.aspx

Infinity88 said...

The fact you should have a default 'zero' value doesn't mean you need one explicitly. One of your 3 values can be the default. I think it would be wierd from calling code for example if they say "Decision." and they see this mysterious Zero value in the list... what is that supposed to mean?

AndrewSeven said...

I thought it was part of the Enum Design Guideline but I don't see it at the moment.

If you specify a value for any member of the enum, you should specify the value for all the enums.

Stephen Salt said...

@infinity88:
I agree completely that it shouldn't be named Zero, as that is meaningless - hence my choice of Unknown. The second link that rajbk posted for Krzysztof's blog contains the guideline I was attempting to follow:

* Do provide a value of zero on your non-flags enum

If None is not appropriate for the enum, then assign the zero-value to the element which should be used as the default value for the enum.

If the enum can logically support the concept of ‘None’, then add a None value to the enum, and give it the zero value