GetName for enum with duplicate values
Experimentation shows that:
V1 = "value1"
and
V2 = "value1"
However, this isn't guaranteed. The MSDN page on Enum.GetName
states:
If multiple enumeration members have the same underlying value, the GetName method guarantees that it will return the name of one of those enumeration members. However, it does not guarantee that it will always return the name of the same enumeration member. As a result, when multiple enumeration members have the same value, your application code should never depend on the method returning a particular member's name.
I disagree with other answers statements
... this isn't guaranteed ...
... you cannot rely on that ...
as well as with msdn statement:
... your application code should never depend on the method returning a particular member's name ...
The story
There was an enum in my software
enum Blabla { A = 0, B = 1, C = 2, D = 3 }
at some point A
value changes to AA
and later AA
changes to AAA
. To keep backward compatibility I had to do
enum Blabla { A = 0, AA = 0, AAA = 0, B = 1, C = 2, D = 3 }
This allows to deserialize old enum value (made by older versions of software) as AAA
.
Then there was a report which prints Blabla
setting value. And at some point every customer using new version start telling me what instead of AAA
they see AA
value. All of them see AA
(and no one report seeing A
).
What I did? I simply change the order (until result was AAA
)
enum Blabla { AAA = 0, A = 0, AA = 0, ...}
and made a test to ensure what Blabla.AAA
will be output as AAA
. Problem solved?
The proof
Looking at sources of Enum.ToString()
(or Enum.GetName()
), it uses GetEnumName(), which calls Array.BinarySearch()
for sorted array of values to find an index of value.
The result of binary search is deterministic: providing it with the same parameters will return same result.
So:
- if you don't change enum, then result will be the same.
- it is possible to find result experimentally (or perhaps by understanding how binary search works and how enum will be processed).
- there is no easy rule to determine result (e.g. you can't say "it always return first defined value").
- it's unlikely what
enum
format will be changed (e.g. order of definition and order of list of values differs) orEnum.ToString()
will be changed, it can happens however, so make sure you have tests for cases where you rely on return value.