tags:

views:

267

answers:

11

I just discovered a subtle bug where I had an enum with two names unintentially sharing the same numeric value (in this case red=10 and crimson=10). I'm a bit surprised this isn't a syntax error.

public enum Colour
{
    Red=10,
    Blue=11,
    Green=12,
    Crimson=10
}
// Debug.Write(Colour.Red==Colour.Crimson) outputs True

Is there any real world reason why this behaviour might be a useful or do think it should be a syntax error?

+2  A: 

Enum is Enumeration of constant variables, and you can have two items with the same value,there is no reason to be a syntax error I think, however, this will cause compile error in this code

switch(c)
{
  Colour.Red:
     break;
  Colour.Crimson:
     break;
  ...
}
ArsenMkrt
It's worth knowing this. It's a reason not to deliberately use share names.
AndyM
Agreed; two names with the same value is not an error. If you'd like to avoid it, do not specify the numeric values.
Stephen Cleary
A: 

I've seen the same thing in a .net TWAIN wrapper - it allows all the TWAIN message codes to be stored in one big enum, but it does make things a bit confusing at first.

Phil
+3  A: 

Enums are used like constans and you definitely can have two constants with the same value which are used in the same places. It can be so because of 3rd party API, because of backward compatibility ot just because of business rules.

wRAR
+1  A: 

It's fine. You could have two values that are different from the point of view of the user of an API, but functionally can be treated as the same value.

Mau
+19  A: 
public enum Colour
{
    Red=10,
    Rouge=10,
    Blue=11,
    Bleu=11,
    Green=12,
    Vert=12,
    Black=13,
    Noir=13
}
Robin Day
Very concise and effective answer.
Neil Aitken
Agreed. Straight to the point no explanation needed.
Gage
And how would you use that? In a multilingual programming team, each member choosing his own constants?
Henk Holterman
I'm at a loss as to how this is an effective answer.
Noldorin
@Henk Holterman this is NOT an answer about a multilingual programming team. This is an answer which indicates a "real world" reason why you might use two different words for the same value in an enum.
Robin Day
@Robin: Like @Noldorin, I fail to see how this is useful. Can you give an example using it?
Henk Holterman
@Henk Holterman: No, I can't give an example of using it. Who in their right mind would create an enum with multi-lingual colours?!? This is an example of how you can use synonyms to represent the same values. Red and Rouge in this instant are identical and therefore should have the same value.
Robin Day
Robin, OK, but the OQ was why it wasn't disallowed so we were looking for an example of _why_ one should use this, not so much for _how_.
Henk Holterman
+3  A: 

It's not a syntax error. All an enum does is enumerate a series of constants in a strongly-typed fashion.

Thus, if a developer mistypes (as in your example), as far as the CLR is concerned, that's a perfectly valid case. The CLR assumes that the developer knows what he's doing, and why he elected to do so.

As for real-world cases, I can't come up with any on the spur-of-the-moment, but I'm still certain that there probably are occasions where it'd be helpful.

John Rudy
+2  A: 

Sure there is, though it's perhaps not too common. If there is an entity/value that is commonly known under two different names, then that is a good reason.

The scenario you have presented is perhaps one such case. An even better one, straight from the BCL, is the System.Windows.Forms.MessageBoxIcon enum; the Stop, Error, and Hand members all have the same description and indeed the same value. Asterisk and Information are also identical, as suggested by the comments:

Asterisk    The message box contains a symbol consisting of a lowercase letter i in a circle.
Information The message box contains a symbol consisting of a lowercase letter i in a circle.

Hopefully this should give you a good idea of appropiate scenarios (your own probably being one).

Noldorin
+5  A: 

I have seen that this feature is sometimes used for a "default" value:

public enum Scope
{
    Transient,
    Singleton,
    Default=Transient
}

But pay attention, this is only sugar for the user of your enum. Just because it is called Default it does not mean that it is the initial value.

tanascius
+1  A: 

Using by named value as opposed to the actual value is root. Suppose you have French, English etc. with the same value. This is the root of enum to me.

Mark Schultheiss
+2  A: 

From the c# language spec:

Multiple enum members may share the same associated value. The example

enum Color 
{
    Red,
    Green,
    Blue,
    Max = Blue
}

shows an enum in which two enum members—Blue and Max—have the same associated value.

In this case you could check for MyColor == Color.Max which would be useful is some circumstances.

etc
A: 

It is sometimes recommended to include a lower and upper bound in your enum such as

public enum Colour
{
    LowBound=10,
    Red=10,
    Rouge=10,
    Blue=11,
    Bleu=11,
    Green=12,
    Vert=12,
    Black=13,
    Noir=13,
    UpperBound=13
}

For the purposes of validation/iterating through each possible setting. Though I have a feeling that .Net may provide a facility for this :)

El Ronnoco