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::实际上,在字符串()或枚举中什么是有效的。