如果我声明一个类似
的枚举enum Weekdays
{
Mon = 1,
Tue = 1,
Wen = 1,
Thi,
Fri,
Sat,
Sun
}
Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);//Prints Tue why?
现在,如果我更改工作日并执行与以下相同的操作
enum Weekdays
{
Mon = 1,
Tue = 1,
Wen = 1,
Thi = 1,
Fri,
Sat,
Sun
}
Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);//Prints Thi !!!!!How?
这里到底发生了什么?
答案 0 :(得分:3)
当您指定相似的值时,结果将是意外的,但我认为它将评估两种情况:
当n为偶数时:
(n/2)
当n为奇数时:
(n/2)+1
如果我像这样更改enum
:
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);
结果为Fri
,现在让我们再次更改enum
:
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);
结果现在为Thi
,再次更改enum
:
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);
结果现在为Thi
,再次更改enum
:
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);
结果现在为Wen
,再次更改enum
:
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);
结果现在为Wen
,再次更改enum
:
enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1}
// n is even = 4
// (n/2) = 2
Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);
结果现在为Tue
,再次更改enum
:
enum Weekdays {Mon=1,Tue=1,Wen=1}
// n is odd = 3
// (n/2)+1 = 2
Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);
结果现在为Tue
。
即使这完全解释了这种行为,但这可能并不总是发生或者可能不会发生,因为我没有检查过更多的情况,但是MSDN说当enum
具有相同的时候你不应该假设这样的输出不同名称的价值......
那就是说,我认为您现在可以很容易地了解代码中发生了什么。
参考:Link
@ GrantWinney的回答让我想到了这一点,他写道Array.BinarySearch
传递了值数组和要搜索的值,所以我从名称Array.BinarySearch
中意识到它是绝对使用BinarySearch
并解释所有内容......
Binary Search会像这样划分数组:
Mid = {Low(which is the starting index) + High (which is the last index of array)}/2
然后检查
if (Mid == value) return index;
else
if the value is smaller or equal move left other wise move right of the array
因此,如果它们是您尝试打印的值的多个名称,则会解释如何打印enum
值。
您的原始问题
enum Weekdays
{
Mon = 1,
Tue = 1,
Wen = 1,
Thi,
Fri,
Sat,
Sun
}
Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);//Prints Tue why?
它打印Tue
,因为调用Array.BinarySearch
将传递数组
{1, 1, 1, 2, 3, 4, 5}
和要搜索的值1
...
所以BinarySearch
会这样做:
Mid = {Low(0) + High(6)} / 2
if (Mid == value) return index
else move left
再次向左移动后,将计算Mid
:
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`
问题中的第二个例子:
enum Weekdays
{
Mon = 1,
Tue = 1,
Wen = 1,
Thi = 1,
Fri,
Sat,
Sun
}
Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);//Prints Thi !!!!!How?
正如我上面所写,将会发出对Array.BinarySearch
的调用和数组:
{1, 1, 1, 1, 2, 3, 4}
将以值= 1
传递给搜索...
在数组上应用BinarySearch
算法,它将评估为Thi
。
答案 1 :(得分:3)
当你像这样写出你的价值时,最终会调用ToString()
。
Console.WriteLine(obj);
如果你深入挖掘代码,它就会在你的价值上调用Enum.GetName()
。
关于具有相同基础值的多个枚举值,MSDN上的Enum.GetName
页面显示:
如果多个枚举成员具有相同的基础值,则GetName方法保证它将返回其中一个枚举成员的名称。但是,它不保证它始终返回相同枚举成员的名称。因此,当多个枚举成员具有相同的值时,您的应用程序代码永远不应该依赖于返回特定成员名称的方法。
如果两个或两个以上的值相同,它不会声明如何确定要返回的名称。
Enum.ToString()
的文档包含相同的警告,措辞略有不同。
深入挖掘,上面的方法调用Array.BinarySearch
,向其传递一个数字数组,表示枚举中的所有值,以及一个代表您要打印的值的数字。
因此,您有一个包含多个1
的数组,并且您正在搜索1
。该调用的docs类似:
允许重复元素。如果Array包含多个等于value的元素,则该方法仅返回其中一个出现的索引,而不一定是第一个出现的索引。
同样,它并没有说明如何进行选择,只是它不可靠。
答案 2 :(得分:2)