Getting element names from enumerations with multiple null values

I'm having difficulty working with some deprecated enumerations that have several null values. Whenever I call ToString on one of the non-zero values, everything except the first zero value is turned on.

Is there a way to isolate a nonzero name without resorting to string manipulation or reflection?

 //all of the following output "Nada, Zilch, One" Console.WriteLine(TestEnum.One); Console.WriteLine(Convert.ToString(TestEnum.One)); Console.WriteLine(TypeDescriptor.GetConverter(typeof(TestEnum)) .ConvertToString(TestEnum.One)); [Flags] enum TestEnum { Zero = 0, Nada = 0, Zilch = 0, One = 1 } 

Edit

I understand that the presence of several elements with the same value is not recommended, however, the specified enumeration is defined in an obsolete assembly, which I cannot change. In fact, there are 12 open enumerations in mscorlib v4 that violate this recommendation, as defined by the following simple LINQ query:

 var types = typeof (void).Assembly.GetTypes() .Where(type => type.IsEnum && type.IsPublic && Enum.GetValues(type).Cast<object>() .GroupBy(value => value) .Any(grp => grp.Count() > 1)) .ToList(); 
+7
source share
4 answers

Here is one of the options. It works, but it's a little ugly. The values โ€‹โ€‹/ names variables will not change, so they will only need to be calculated.

Assuming you have a slightly more complex enumeration, for example:

 [Flags] public enum TestEnum { Zero = 0, Nada = 0, Zilch = 0, One = 1, Two = 2, Three = 3, Four = 4 } 

Here is the code you can use:

 var input = TestEnum.One | TestEnum.Two; var values = (TestEnum[]) Enum.GetValues(typeof (TestEnum)); var names = Enum.GetNames(typeof (TestEnum)); var result = values .Select((value, index) => input == value || (value != 0 && (input & value) == value) ? names[index] : null) .Where(name => name != null); var text = string.Join(", ", result); Console.WriteLine(text); 
+1
source

Well, first Microsoft recommends against this . Some of the more powerful words I heard from them use for something that they don't apply when compiling:

Avoid setting the flag enumeration value to zero unless the value is used to indicate that all flags are cleared. Such a value should be named appropriately, as described in the next guide ... Name the null value of the flag enumerations None. To enumerate flags, a value should always mean that all flags are cleared.

OK, so why is this happening? From this question, I accept its Enum.ToString , behaving strangely:

If several enumeration elements have the same base value, and you are trying to get a string representation of the name of an enumeration member based on its base value, your code should not make any assumptions about which name the method returns.

EDIT: I can reproduce your results, but I can no longer find the documentation about why it will start printing other values โ€‹โ€‹of 0. I would expect it to print NONE of them.

Can you just right-click-> refactor-> rename them anyway and then delete the rest? Everything seems to be simpler and more efficient than Microsoft recommends.

+1
source
 Enum.GetValues(typeof (TestEnum)) 

returns

 {ClassLibrary5.Class1.TestEnum[4]} [0] Zilch ClassLibrary5.Class1.TestEnum [1] Zilch ClassLibrary5.Class1.TestEnum [2] Zilch ClassLibrary5.Class1.TestEnum [3] One ClassLibrary5.Class1.TestEnum 

I was about to quote the same passage as Dan. What should they be used for? What do you need to do with these listings?

0
source

Assuming you have a slightly more complex enumeration, for example:

 [Flags] public enum TestEnum { Zero = 0, Nada = 0, Zilch = 0, One = 1, Two = 2, Four = 4, } 

You can implement a simple method that returns a string value for you, for example:

 public static string TestEnumToString(TestEnum value) { var result = new List(); if (value == TestEnum.Zero) { result.Add("Zero"); } if (value == TestEnum.Nada) { result.Add("Nada"); } if (value == TestEnum.Zilch) { result.Add("Zilch"); } if ((value & TestEnum.One) != 0) { result.Add("One"); } if ((value & TestEnum.Two) != 0) { result.Add("Two"); } if ((value & TestEnum.Four) != 0) { result.Add("Four"); } return string.Join(",", result); } 
0
source

All Articles