Using an enumeration containing records with the same base type value

if I declare an enumeration like

enum Weekdays { Mon = 1, Tue = 1, Wen = 1, Thi, Fri, Sat, Sun } Weekdays obj = (Weekdays)1; Console.WriteLine(obj);//Prints Tue why? 

Now, if I change weekdays and perform the same operation as

 enum Weekdays { Mon = 1, Tue = 1, Wen = 1, Thi = 1, Fri, Sat, Sun } Weekdays obj = (Weekdays)1; Console.WriteLine(obj);//Prints Thi !!!!!How? 

What is really going on here?

+1
enums c #
Oct 12 '14 at 3:18
source share
3 answers

When assigning such values, the result will be unexpected, but I think that it will be evaluated in two cases:

When n is equal to:

 (n/2) 

When n is odd:

 (n/2)+1 

If I changed enum as follows:

 enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1,Fri=1,Sat=1, Sun=1, Mon2=1, Mon3=1} // n is odd = 9 // (n/2)+1 = 5 Weekdays obj = (Weekdays)1; Console.WriteLine(obj); 

The result will be Fri , now change enum again:

 enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1,Fri=1,Sat=1, Sun=1,Mon2=1} // n is even = 8 // (n/2) = 4 Weekdays obj = (Weekdays)1; Console.WriteLine(obj); 

Now Thi result, change enum again:

 enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1,Fri=1,Sat=1, Sun=1} // n is odd = 7 // (n/2)+1 = 4 Weekdays obj = (Weekdays)1; Console.WriteLine(obj); 

Now Thi result, change enum again:

 enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1,Fri=1,Sat=1} // n is even = 6 // (n/2) = 3 Weekdays obj = (Weekdays)1; Console.WriteLine(obj); 

Now the result of Wen , change enum again:

 enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1,Fri=1} // n is odd = 5 // (n/2)+1 = 3 Weekdays obj = (Weekdays)1; Console.WriteLine(obj); 

Now the result of Wen changing enum again:

 enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1} // n is even = 4 // (n/2) = 2 Weekdays obj = (Weekdays)1; Console.WriteLine(obj); 

Now the result of Tue , again changing enum :

 enum Weekdays {Mon=1,Tue=1,Wen=1} // n is odd = 3 // (n/2)+1 = 2 Weekdays obj = (Weekdays)1; Console.WriteLine(obj); 

Now the result is Tue

Although this explains the behavior perfectly, it may not always happen or it may not happen because I did not check for more cases, but since MSDN says you should not assume such an output when enum have the same values ​​for different names ...

However, I think you can easily understand what is going on in your code.

Link: Link

Edit:

@ GrantWinney's answer led me to this, he wrote that Array.BinarySearch is passed an array of values ​​and a value for the search, so I understood from the name Array.BinarySearch that it definitely uses BinarySearch and that explains everything ...

Binary search will split the array as follows:

 Mid = {Low(which is the starting index) + High (which is the last index of array)}/2 

and then check

 if (Mid == value) return index; else if the value is smaller or equal move left other wise move right of the array 

So this explains how enum values ​​are printed if there are several names for the value you are trying to print.

Your original question

 enum Weekdays { Mon = 1, Tue = 1, Wen = 1, Thi, Fri, Sat, Sun } Weekdays obj = (Weekdays)1; Console.WriteLine(obj);//Prints Tue why? 

It prints Tue because the call to Array.BinarySearch will be executed with an array transfer

 {1, 1, 1, 2, 3, 4, 5} 

and the value for the search, which is 1 ...

So, BinarySearch will do the following:

 Mid = {Low(0) + High(6)} / 2 if (Mid == value) return index else move left 

After moving to the left, Mid will be calculated again:

 High = Mid - 1; // now only the left sub-array will be searched Mid = {Low(0) + High(2)} / 2 if (Mid == value) return index // here the condition will be true and you will be returned with `Tue` 

Second example in your Question:

 enum Weekdays { Mon = 1, Tue = 1, Wen = 1, Thi = 1, Fri, Sat, Sun } Weekdays obj = (Weekdays)1; Console.WriteLine(obj);//Prints Thi !!!!!How? 

As I wrote above, the call to Array.BinarySearch and the array will be executed:

 {1, 1, 1, 1, 2, 3, 4} 

will be passed with value = 1 to search ...

Apply the BinarySearch algorithm to the array and it will evaluate to Thi .

+3
Oct. 12 '14 at 3:51
source share

When you write out your value like this, it ends up calling ToString() .

 Console.WriteLine(obj); 

If you dig the code far enough, it calls Enum.GetName() according to your value.

Regarding multiple enum values ​​with the same base value, the Enum.GetName page on MSDN says:

If multiple enumeration elements have the same base value, the GetName method ensures that it returns the name of one of these enumeration elements. However, it does not guarantee that it will always return the name of the same enumeration element. As a result, when multiple enumeration elements have the same value, your application code should never depend on a method that returns a specific member name.

It does not indicate how it determines which name will be returned if the values ​​on two or more are the same.

The docs for Enum.ToString() include the same warning in slightly different wording.

Digging a little deeper, the method above makes an call to Array.BinarySearch , passing it an array of numbers representing all the values ​​in your enum and a number representing the value you want to print.

So you have an array with several 1 in it and you are looking for 1 . The docs for this call are similar:

Duplicate elements allowed. If the array contains more than one element equal to the value, the method returns the index of only one of the entries, and not necessarily the first.

Again, it does not indicate how the choice is made, it will simply be unreliable.

+3
Oct 12 '14 at 4:02
source share



All Articles