user1664043
user1664043

Reputation: 705

C# synonymous enum handling

This is either too clever by half or not clever enough by 62.784%. For odd reasons, our product management decided they wanted to rename some of our enum values and how they serialize. After a couple of builds they decided they wanted it to be backwards compatible - i.e. read and process old serializations to the new values.

I thought I'd try declaring the new name in the enum first, then declaring OldName = NewName just after as a synonym, hoping that the equivalency would get worked out in the wash in favor of the first declaration and it would automagically translate old to new with Enum.Parse.

I worked up a little sample app like so:

public enum syns
{
    Zero,
    One,
    Two,
    Three = Two,
    Four,
};

public string SynTest()
{
    string result;
    syns synTest2 = (syns)syns.Two, synTest3;
    bool okay = Enum.TryParse<syns>("Three", out synTest3);
    result = (okay).ToString() + "," + (synTest2 == synTest3).ToString() + "," + synTest2.ToString() + "," + synTest3.ToString() + ",";
    synTest3 = (syns)Enum.Parse(typeof(syns), "Three");
    result += synTest3.ToString();
    return result;
}

and got what I wanted. The old name "Three" parsed, and when the parsed value was evaluated it produced the new name Two every which way. Yay.

So I used the technique in our actual code (a much longer enum, with lots of app-specific names/values, etc). Worked on my machine, so I checked it in.

The problem we're having is that there doesn't appear to be any consistency in how this is handled. The build got to QA, and (the equivalent of) "Three" parsed and stayed as Three throughout (old name) rather than evaluating to the new version Two.

After pulling on this thread for a while, it seems like about 50% of the machines we've tried it on process it the way my machine did (new value prevailing) and 50% skew to the old name.

I tried pulling all of the test cases into a test.aspx page, and my test.aspx page behaves differently than the underlying assemblies. And in the test.aspx page, the enum above behaves differently from the actual enum from our code base.

  1. Any hints as to what determines how evaluations of synonym enums lean?
  2. Any ideas why the same assemblies would change behavior machine to machine? All the machines are set to target framework 4.5.1, and at least on the couple I compared it seemed they were at the same patch level.
  3. Even on a machine where I got the desired behavior, pulling the same declaration into a test.aspx changed the behavior, so I was wondering if this is fickle on a file-by-file basis.

Upvotes: 4

Views: 561

Answers (1)

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391286

This is "clearly" documented under Enum.ToString:

Notes to Callers
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.

(my emphasis)

This is documented to have unspecified behavior. There may in fact be a observable (seemingly) consistent behavior on one machine depending on the .NET runtime version, .NET hotfixes installed etc. etc. but you cannot make any guarantees that it will continue to behave like that tomorrow or next week.

In short, you cannot do it this way, you need to find another way to handle the aliasing.

Upvotes: 5

Related Questions