2

For illustration, I've an enum class Genre with different enum fields and ToString() method will produce different results under different scenarios.

For examples,

Case 1:

public enum Genre {
     A1 = 1,  // .ToString() produces "A2"
     A2 = A1, // .ToString() produces "A2"
     B1 = 2,  // .ToString() produces "B1" (Why not "B2"?)
     B2 = B1  // .ToString() produces "B1" (Why not "B2"?)
}

Case 2:

public enum Genre {
    A1 = 1,  // .ToString() produces "A2"
    A2 = A1, // .ToString() produces "A2"
    B1 = 2   // .ToString() produces "B1"
}

Case 3:

public enum Genre {
    A1 = 1,  // .ToString() produces "A1" (Why not "A2"?)
    A2 = A1  // .ToString() produces "A1" (Why not "A2"?)
}

Below are the experiment screenshots that I had done via Rider's Immediate Window. Another workaround is to use nameof() but major places in our code base are using ToString() and we do not want to change them.

Case 1

Case 2

Case 3

Evan
  • 23
  • 4
  • 1
    If you have enum constants with the same underlying values, then it is correct for `ToString` to return the name of any of the enum members with the same underlying value. See the [documentation](https://learn.microsoft.com/en-us/dotnet/api/system.enum.tostring?view=net-7.0#system-enum-tostring) – Sweeper Apr 20 '23 at 07:15
  • That said, why are you declaring enums like this? Why `A2 = A1` and `B2 = B1`? If you want consistent behaviour from `ToString`, you need to get rid of those. – Sweeper Apr 20 '23 at 07:18
  • @Sweeper: It's the same if he would use duplicate constant values. Why he should not use the same value multiple times? Enums are designed to support this, actually it's similar to a class which has multiple constants declared that share the same value. If he must rely on the name he should use a `Dictionary` – Tim Schmelter Apr 20 '23 at 07:33
  • @TimSchmelter I assumed that this behaviour of `ToString` is undesirable to OP, so they should not use duplicate constant values, and should find another way of doing whatever they are trying to by using duplicate constant values. i.e. I suspected that this is an [XY Problem](http://xyproblem.info/). – Sweeper Apr 20 '23 at 07:36
  • @Sweeper: if you use same same value multiple times that's not done by mistake but because they have the same value(they mean the same, if you work with the value). So it's not a solution to change that just because `ToString` returns unpreditable names. Then better find a different way to map the name(like the dictionary or a class). – Tim Schmelter Apr 20 '23 at 07:40
  • Does this answer your question? [Enum.ToString return wrong value?](https://stackoverflow.com/questions/10268250/enum-tostring-return-wrong-value) – Charlieface Apr 20 '23 at 09:48

1 Answers1

3

The docs state:

If multiple enumeration members have the same underlying value and you attempt to retrieve the string representation of an enumeration member's name based on its underlying value, your code should not make any assumptions about which name the method will return.

If you look at the source, you see the reason is that Enum.ToString uses GetEnumName which uses GetEnumData which uses reflection to get the names of all enum values, then uses Array.BinarySearch to find the first matching. So it's not predictable what name you get and you should not rely on it.

If you must rely on the name you should consider to use a Dictionary<Genre, string> or a real class, for example FilmGenre which has string Name and maybe Genre Genre properties.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939