C# 使用具有与基础类型具有相同值的项的枚举

C# 使用具有与基础类型具有相同值的项的枚举,c#,.net,enums,C#,.net,Enums,如果我声明一个枚举,比如 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 =

如果我声明一个枚举,比如

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?

这里到底发生了什么?

根据MSDN,当您指定类似的值时,结果将出乎意料,但我认为它将评估两种情况:

当n为偶数时:

(n/2)
(n/2)+1
enum Weekdays
{
    Mon = 1,
    Tue = 1,
    Wen = 1,
    Thi = 1,
    Fri,
    Sat,
    Sun
}

Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);//Prints Thi !!!!!How?
当n为奇数时:

(n/2)
(n/2)+1
enum Weekdays
{
    Mon = 1,
    Tue = 1,
    Wen = 1,
    Thi = 1,
    Fri,
    Sat,
    Sun
}

Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);//Prints Thi !!!!!How?
如果我像这样更改
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);
Mid = {Low(which is the starting index) + High (which is the last index of array)}/2
结果将是
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);
enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1}
// n is even = 4
// (n/2) = 2

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

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);
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);
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);
结果现在是
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);
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);
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,Fri=1,Sat=1, Sun=1}
// n is odd = 7
// (n/2)+1 = 4

Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);
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);
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,Fri=1,Sat=1, Sun=1,Mon2=1}
// n is even = 8
// (n/2) = 4

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

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

Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);
结果现在是
Tue
,再次更改
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);
enum Weekdays {Mon=1,Tue=1,Wen=1,Thi=1}
// n is even = 4
// (n/2) = 2

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

Weekdays obj = (Weekdays)1;
Console.WriteLine(obj);
结果现在是星期二

尽管这很好地解释了该行为,但这可能并不总是发生,也可能不会发生,因为我没有检查更多的情况,但正如MSDN所说,当
enum
对不同的名称具有相同的值时,您不应该假设这样的输出

也就是说,我认为您现在可以很容易地理解代码中发生了什么

参考号:

编辑: @GrantWinney的回答让我想到了这一点,他写了
Array.BinarySearch
传递了值数组和要搜索的值,因此我从名称
Array.BinarySearch
中意识到它肯定使用了
BinarySearch
,这解释了一切

将按如下方式分割数组:

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);
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`
问题中的第二个例子:

(n/2)
(n/2)+1
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
当您这样写出值时,它最终会被调用
ToString()

Console.WriteLine(obj);
如果您深入研究代码,它将对您的值调用
Enum.GetName()

关于具有相同基础值的多个枚举值,上的
enum.GetName
页面显示:

如果多个枚举成员具有相同的基础值,则GetName方法保证返回其中一个枚举成员的名称。但是,它不能保证总是返回同一枚举成员的名称。因此,当多个枚举成员具有相同的值时,应用程序代码不应依赖于返回特定成员名称的方法

如果两个或多个上的值相同,它不会说明如何确定返回哪个名称

的文档包含相同的警告,但措辞略有不同

再深入一点,上面的方法调用
Array.BinarySearch
,向它传递一个表示枚举中所有值的数字数组,以及一个表示要打印的值的数字

因此,您有一个包含多个
1
的数组,您正在搜索
1
。该电话的电话号码与此类似:

允许重复元素。如果数组包含多个等于value的元素,则该方法只返回其中一个实例的索引,而不一定返回第一个实例的索引


同样,它没有说明选择是如何进行的,只是说明选择是不可靠的。

如果将3天或4天链接到同一个数字:1,则在3天或4天中随机出现一天,这是不可预测的。你为什么想要3天或4天的相同数字?我只是在检查它们得到相同值时会发生什么,你是对的,我们无法以任何方式预测MSDN的输出。谢谢你的dude:在你的枚举中,所有常量都有相同的值,如果我的枚举像
enum WeekDays{Mon=1,Tue=1,Wen,Thi,Fri=1,sat,Sun};工作日obj=(工作日)1;控制台写入线(obj)//打印fri
你能告诉我为什么吗?是的,我更改了它,因为我试图解释当枚举中不同名称的值相同时会发生什么。@ShamseerKSmr我还不能,但是我写过,在我的答案中有一个模式,但这不可能是100%,因为它写在MSDN上,当枚举对不同的名称具有相同的值时,输出将是意外的…不知道尝试对.Net如何进行反向工程有多大的建设性。不同版本的.Net中的实现可能不同,Microsoft可能会在将来的版本中更改该实现。然后是Mono,以及(希望)未来将出现的其他C#实现,每种实现都可能有不同的实现方式。@SyedFarjadZiaZaidi:现在你说enum肯定使用了二进制搜索,这就解释了一切。如果是这样,我的枚举是这样的
enum WeekDays{Mon=1,Tue=1,Wen,Thi,Fri=1,sat,Sun}
现在尝试下面的代码
WeekDays obj=(WeekDays)1;控制台写入线(obj)//周五打印
你能解释一下原因吗?根据你的解释,它必须在周二打印,但不是。嘿,你能读一下我的答案并告诉我它是否有意义吗?@grant winney::实际上,在字符串()或枚举中什么是有效的。