新手提问:关于枚举(enum)类型的疑问?

浴火_凤凰 2009-12-30 11:06:45
请首先看一下下面的代码:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
enum weekday
{
Sunday,
Monday,
Tuesday,
}
static void Main(string[] args)
{
switch (weekday.Sunday)
{
case 0: Console.WriteLine("今天是" + weekday.Sunday);break;
case weekday.Monday: Console.WriteLine("今天是" + weekday.Monday);break;
case weekday.Tuesday: Console.WriteLine("今天是" + weekday.Tuesday); break;
}
Console.Read();
}
}
}

/*
疑问一:C# 中的switch语句必须使用break;吗?没有的话会报以下错误:
Control cannot fall through from one case label ('case 0:') to another
疑问二:第一个case语句为0和weekday.Sunday都能得到执行,但是后面的case语句为
数字的话,则报错,请问这是为什么啊?
疑问三:打印出weekday.Sunday的结果为Sunday,但是在case语句中写Sunday或者"Sunday"都会
报错,为什么?输出结果的Sunday到底是一个什么类型?
疑问四:在枚举声明时可以使用Tuesday=55语句,但是却在输出结果语句中仍然为Tuesday,
怎样才是55?还有Tuesday赋值为其它数据类型就会报错。
*/

呵呵,初学C#,脑子中也不知道怎么就冒出来这么多的疑问,
希望各位多多帮助,再次感谢各位的帮忙!谢谢!!!
...全文
364 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
浴火_凤凰 2009-12-31
  • 打赏
  • 举报
回复
我想说明几点,首先我并不是没有经过思考就问这些问题的,
其次我也不是没有看书,但是书上只是一带而过。
我是从其它语言转变过来的,所以也有了一些编程基础,我把我的真实想法说一下
大家就明白了。
疑问一:C# 中的switch语句必须使用break;吗?没有的话会报以下错误:
Control cannot fall through from one case label ('case 0:') to another

因为我所知道的C和C++、JavaScript、Java都支持case语句后面没有break;这种写法,所以才有此一问,
并不是没有看书就直接来提问的,我只想说的是我是经过了思考的。
疑问二:第一个case语句为0和weekday.Sunday都能得到执行,但是后面的case语句为
数字的话,则报错,请问这是为什么啊?
我也知道枚举默认是从0开始的,而且我也知道可以改变它的默认起始值。
但是我想问的不是这些,请大家认真看看12楼的问题再回答,好吗?
疑问三:打印出weekday.Sunday的结果为Sunday,但是在case语句中写Sunday或者"Sunday"都会
报错,为什么?输出结果的Sunday到底是一个什么类型?
至于这个疑问是因为我习惯了变量或者常量的名称和值是不同的情况,
这里的常量的名称为weekday.Sunday而常量的值为Sunday,貌似二者一样,不太习惯,所以有此疑问。
疑问四:在枚举声明时可以使用Tuesday=55语句,但是却在输出结果语句中仍然为Tuesday,
怎样才是55?还有Tuesday赋值为其它数据类型就会报错。
至于这个问题,我承认是我的疏忽,没有在书上看到这部分内容,也许是跟我的书籍有关系吧,
我看的是基础教程,书上貌似真的没有提到怎样获取Tuesday=55中的55.

我之所以说这么多,只是怕大家误会我是一个好吃懒做的家伙,
怕大家把我当成一个不会思考只会粘贴代码的人,
我知道程序员最烦这种人了,
我只想说我的疑问都是经过了我的思考之后才发问的,
谢谢大家耐心的把我的这段话看完,
也再次感谢大家的热心帮助!!!
谢谢!!!
xuyiazl 2009-12-31
  • 打赏
  • 举报
回复
稀客稀客~
龙宜坡 2009-12-31
  • 打赏
  • 举报
回复
[Quote=引用楼主 kingwolf_javascript 的回复:]
/*
疑问一:C# 中的switch语句必须使用break;吗?没有的话会报以下错误:
Control cannot fall through from one case label ('case 0:') to another
疑问二:第一个case语句为0和weekday.Sunday都能得到执行,但是后面的case语句为
数字的话,则报错,请问这是为什么啊?
疑问三:打印出weekday.Sunday的结果为Sunday,但是在case语句中写Sunday或者"Sunday"都会
报错,为什么?输出结果的Sunday到底是一个什么类型?
疑问四:在枚举声明时可以使用Tuesday=55语句,但是却在输出结果语句中仍然为Tuesday,
怎样才是55?还有Tuesday赋值为其它数据类型就会报错。
*/

[/Quote]

1.在每一个 case 块(包括上一个块,不论它是 case 语句还是 default 语句)的后面,都必须有一个跳转语句(如 break)。

2.别那么写
因为使用时并不知道枚举类型真正的枚举常量是多少。
正确的写法应该是
            weekday _day = weekday.Sunday;
switch (_day)
{
case weekday.Sunday:
Console.WriteLine("今天是" + weekday.Sunday);
break;
case weekday.Monday:
Console.WriteLine("今天是" + weekday.Monday);
break;
case weekday.Tuesday:
Console.WriteLine("今天是" + weekday.Tuesday);
break;
}


3.打印出weekday.Sunday的结果为Sunday,但是在case语句中写Sunday或者"Sunday"都会
报错,为什么?

case表达式必须为一常量值。

输出结果的Sunday到底是一个什么类型?


Console.WriteLine("今天是" + weekday.Sunday);
此处隐式调用了weekday..Sunday.ToString()方法,与
Console.WriteLine("今天是" + weekday.Sunday.ToString());无异。

4.强制转换(int)weekday.Tuesday
kensouterry 2009-12-31
  • 打赏
  • 举报
回复
那个WeekDay.Sunday为什么可以执行我也不是很清楚!
卧_槽 2009-12-31
  • 打赏
  • 举报
回复
书上有的,我就不说了
kensouterry 2009-12-31
  • 打赏
  • 举报
回复
强制转换一下:
swtich((int)weekday.Monday)
浴火_凤凰 2009-12-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 kensouterry 的回复:]
enum 关键字用于声明枚举,即一种由一组称为枚举数列表的命名常量组成的独特类型。每种枚举类型都有基础类型,该类型可以是除 char 以外的任何整型。枚举元素的默认基础类型为 int。默认情况下,第一个枚举数的值为 0,后面每个枚举数的值依次递增 1。例如:

  复制代码
      enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};


在此枚举中,Sat 为 0,Sun 为 1,Mon 为 2,依此类推。枚举数可以具有重写默认值的初始值设定项。例如:

  复制代码
      enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};


在此枚举中,强制元素序列从 1 而不是 0 开始。

若要声明另一整型枚举,例如 byte,请在标识符之后紧跟类型,然后再使用冒号:

  复制代码
enum Days : byte {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};


准许使用的枚举类型有 byte、sbyte、short、ushort、int、uint、long 或 ulong。


不爱看书的孩子!
你的代码:
enum weekday
        {
            Sunday,
            Monday,
            Tuesday,
        }

swtich(weekDay.Sunday)//这里你的sunday就为0,下面的case 1当然会出错了!
{
  case 0:
}
[/Quote]
不好意思,我想你是没有看懂我问题的意思
我的问题是:
swtich(weekday.Sunday)的时候,case 0:语句会执行。
swtich(weekday.Monday)的时候,case 1:语句却会报错,这里的Monday不就相当于1吗?如果是类型不匹配的问题,那么上面的weekDay.Sunday和0就能匹配吗?。
kensouterry 2009-12-31
  • 打赏
  • 举报
回复
enum 关键字用于声明枚举,即一种由一组称为枚举数列表的命名常量组成的独特类型。每种枚举类型都有基础类型,该类型可以是除 char 以外的任何整型。枚举元素的默认基础类型为 int。默认情况下,第一个枚举数的值为 0,后面每个枚举数的值依次递增 1。例如:

复制代码
enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};


在此枚举中,Sat 为 0,Sun 为 1,Mon 为 2,依此类推。枚举数可以具有重写默认值的初始值设定项。例如:

复制代码
enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};


在此枚举中,强制元素序列从 1 而不是 0 开始。

若要声明另一整型枚举,例如 byte,请在标识符之后紧跟类型,然后再使用冒号:

复制代码
enum Days : byte {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};


准许使用的枚举类型有 byte、sbyte、short、ushort、int、uint、long 或 ulong。


不爱看书的孩子!
你的代码:
enum weekday
{
Sunday,
Monday,
Tuesday,
}

swtich(weekDay.Sunday)//这里你的sunday就为0,下面的case 1当然会出错了!
{
case 0:
}
浴火_凤凰 2009-12-31
  • 打赏
  • 举报
回复
首先感谢楼上各位的热心回答,谢谢!!!

不过疑问还是有部分没有解开,希望能再说的详细一点,谢谢!!!

疑问二:第一个case语句为0和weekday.Sunday都能得到执行,但是后面的case语句为
数字的话,则报错,请问这是为什么啊?
我的意思是
switch (weekday.Sunday)
{
case 0: Console.WriteLine("今天是" + weekday.Sunday);break;//0也会执行,为什么?难不成是C#的Bug???
}

switch (weekday.Monday)
{
case 1: Console.WriteLine("今天是" + weekday.Monday);break;上面的0会执行,这里的1却会报错,不明白?
}


疑问四:在枚举声明时可以使用Tuesday=55语句,但是却在输出结果语句中仍然为Tuesday,
怎样才是55?还有Tuesday赋值为其它数据类型就会报错。
枚举不仅仅是常量的集合吧?一般的常量
const int aa=55;就算打印aa也会输出55吧,不会输出常量的名字,而枚举却会输出常量的名字。
如:打印weekday.Sunday枚举会输出常量的名字Sunday
starj1 2009-12-31
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 kingwolf_javascript 的回复:]
...
疑问一:C# 中的switch语句必须使用break;吗?没有的话会报以下错误:
Control cannot fall through from one case label ('case 0:') to another

...
疑问三:打印出weekday.Sunday的结果为Sunday,但是在case语句中写Sunday或者"Sunday"都会
报错,为什么?输出结果的Sunday到底是一个什么类型?
至于这个疑问是因为我习惯了变量或者常量的名称和值是不同的情况,
这里的常量的名称为weekday.Sunday而常量的值为Sunday,貌似二者一样,不太习惯,所以有此疑问。
...[/Quote]

C#的case非空分支必须用break或其它形式跳出,这是C#本身的语法规定,没什么好讨论的。
至于疑问三,case语句写什么或什么那是编译通不过,也就是说,写法不被编译器承认。输出结果的Sunday就是一个字符串。前面已经有回答了,枚举的ToString()编译器已经自动重写到成员的名称。
rainsnowclowd 2009-12-30
  • 打赏
  • 举报
回复
疑问一:C# 中的switch语句必须使用break;吗?没有的话会报以下错误:

c#不支持上個case执行完跳到下一个case执行,除非上一个case是空的,就是没有执行代码,否则就必须跳出。
不清楚其他的语言支持不~~没试过

疑问二:第一个case语句为0和weekday.Sunday都能得到执行,但是后面的case语句为
数字的话,则报错,请问这是为什么啊?

这个我也解释不清楚,可能没有enum没有实现隐式转换吧
switch改下呗,改成switch((int)Weekday.Sunday)就可以了

疑问三:打印出weekday.Sunday的结果为Sunday,但是在case语句中写Sunday或者"Sunday"都会
报错,为什么?输出结果的Sunday到底是一个什么类型?

你打印的時候它会默认调用ENUM的ToString方法,要不然你怎么打印呢。。
enum重写了ToString方法,就是以字符串方式输出当前enum的值,要输出数字,就像楼上的说的一样用(int)转换下就可以了。或者你自己再重写一下ToString方法

疑问四:在枚举声明时可以使用Tuesday=55语句,但是却在输出结果语句中仍然为Tuesday,
怎样才是55?还有Tuesday赋值为其它数据类型就会报错。

enum只能是数值型的。char也算数值型,可以赋值的。 然后前半部分同第三个疑问一样哦。都是自动调用ToString方法了
biny101 2009-12-30
  • 打赏
  • 举报
回复
UP 又学到东西了
m_struggle 2009-12-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 huming_h 的回复:]
首先这个不叫结构体,叫枚举
疑问一:这是switch的书写规则。
疑问二:你这样书写就没有问题了
weekday type=weekday.Monday;//定义一个变量

switch(type)//而不是传一个固定的值来判断
{
  case weekday. Sunday:
    break;
  case weekday. Monday;
}
疑问三:直接输入sunday,相当于没有定义,

疑问四:想要得到55 (int)weekday. Tuesday
[/Quote]

支持
kensouterry 2009-12-30
  • 打赏
  • 举报
回复
哇 楼上的好详细啊 Mark!
kensouterry 2009-12-30
  • 打赏
  • 举报
回复
除了使用break,还可以用goto进行标签跳转!


huming_h 2009-12-30
  • 打赏
  • 举报
回复
首先这个不叫结构体,叫枚举
疑问一:这是switch的书写规则。
疑问二:你这样书写就没有问题了
weekday type=weekday.Monday;//定义一个变量

switch(type)//而不是传一个固定的值来判断
{
case weekday. Sunday:
break;
case weekday. Monday;
}
疑问三:直接输入sunday,相当于没有定义,

疑问四:想要得到55 (int)weekday. Tuesday
antony1029 2009-12-30
  • 打赏
  • 举报
回复
1.控制传递给与开关的值匹配的 case 语句。switch 语句可以包括任意数目的 case 实例,但是任何两个 case 语句都不能具有相同的值。语句体从选定的语句开始执行,直到 break 将控制传递到 case 体以外。在每一个 case 块(包括上一个块,不论它是 case 语句还是 default 语句)的后面,都必须有一个跳转语句(如 break)。但有一个例外,(与 C++ switch 语句不同)C# 不支持从一个 case 标签显式贯穿到另一个 case 标签。这个例外是当 case 语句中没有代码时。

如果没有任何 case 表达式与开关值匹配,则控制传递给跟在可选 default 标签后的语句。如果没有 default 标签,则控制传递到 switch 以外。

switch语句非常有用,但在使用时必须谨慎。所写的任何switch语句都必须遵循以下规则:
只能针对基本数据类型使用switch,这些类型包括int和string等待。对于其他类型,则必须使用if语句。
case标签必须是常量表达式(constantExpression),如42或者"42"。如果需要在运行时计算case标签的值,必须使用if语句。
case标签必须是惟一性的表达式;也就是说,不允许两个case具有相同的值。
可以连续写下一系列case标签(中间不能间插额外的语句),从而指定自己希望在多种情况下都运行相同的语句。如果像这样写,那么最后一个case标签之后的代码将适用于所有case。然而,假如一个标签关联了一个或多个语句,又没有使用break来跳出,那么执行就不能贯穿到后续的标签,而且编译器会报告一个错误。例如:
switch (trumps)
{
case Hearts :
case Diamonds : // 允许贯穿 — 标签之间无额外代码
color = "Red"; // 针对Hearts和Diamonds这两种情况都会执行的代码
break;
case Clubs :
color = "Black";
case Spades : // 出错 — 标签之间有额外代码,而且没有使用break来跳出
color = "Black";
break;
}
注意 break语句是用来阻止贯穿的最常见的方式,但也可以用一个return语句或者一个throw语句来替代它.

2.enum 关键字用于声明枚举,即一种由一组称为枚举数列表的命名常量组成的独特类型。每种枚举类型都有基础类型,该类型可以是除 char 以外的任何整型。枚举元素的默认基础类型为 int。默认情况下,第一个枚举数的值为 0,后面每个枚举数的值依次递增 1。
Tuesday=55 这个枚举 你要取55的话 可以转换为int。或取它的hashcode值。
int x = (int)weekday.Tuesday;
  • 打赏
  • 举报
回复
enum weekday
{
Sunday=0,
Monday=1,
Tuesday=2,
}
默认是从0开始的索引,这个你也可以自己指定:
enum weekday
{
Sunday=1,
Monday=3,
Tuesday=5,
}
hbmy9107lwt 2009-12-30
  • 打赏
  • 举报
回复
niu

111,120

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧