温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C#枚举赋值的方法是什么

发布时间:2021-12-03 09:27:35 来源:亿速云 阅读:200 作者:iii 栏目:编程语言

这篇文章主要讲解了“C#枚举赋值的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#枚举赋值的方法是什么”吧!

Q:我留意到Code #02中的

.field public static literal Aligment Center = int32(0x00000001)

该语句明显是整数赋值,这是否说明C#枚举类型实质上是整数类型?

A:这说明枚举类型与整数类型的确有一定的关系。事实上,每一个枚举类型都有与之相对应的整数类型,我们称该整数类型为底层类型(underlying type),默认的情况下使用,.NET使用System.Int32。当然,你可以手动将其指定为其他的整数类型:

// Code #09  public enum Alignment : byte {      Left,      Center,      Right  }

注意,能被指定为枚举的底层类型的只能是如下所列的整数类型:byte, sbyte, short, ushort, int, uint, long, ulong。

--------------------------------------------------------------------------------

Q:为何我们需要指定枚举类型的底层类型?

A:你完全可以让它接受默认的底层类型。请留意Code #08,你完全找不到“Center”这个字眼,然而在C#代码中,它却是存在的,为什么呢?这是因为代码在编译的时候,编译器把枚举类型转换为与之对应的底层类型的数值来处理。Code #08的L_0000实际上就是把类型为System.Int32的数值1推入堆栈,而不是把“Center”推入堆栈。事实上,底层类型说明了如何为枚举类型分配空间,不同的底层类型所占用的资源不同,大概当你在受限系统上进行开发的话,你就可能需要注意一下了。

--------------------------------------------------------------------------------

C#枚举的赋值

Q:枚举成员的值是怎样规定的?

A:如果你没有手动指定成员的值的话,从上往下看,各成员的值为:0, 1, 2, ...。说罢了,就是一个非负整数等差数列,其初值为0,步长为1。例如:

// Code #10  public enum Alignment  {      Left,    // 0      Center,    // 1      Right    // 2  }

--------------------------------------------------------------------------------

Q:如果我有手动指定某些成员的值呢?

A:那么被赋值的成员的值就是你所指定的值。当然,无论你是否手动指定枚举成员的值,递增步长都不会变,总是为1。为了测试你是否理解,请说出下面枚举个成员的值以及你的判断理由(请用人脑而不是电脑来运行以下代码):

// Code #11  public enum DriveType : sbyte {      CDRom,      Fixed = -2,      Network,      NoRootDirectory = -1,      Ram,      Removable = Network * NoRootDirectory,      Unknown  }

--------------------------------------------------------------------------------

Q:我们如何获取枚举成员的值,无论成员是否被手动赋值?

A:你可以使用System.Enum的

public static Array GetValues(Type enumType);

该方法返回一个包含所有枚举成员的数组:

// Code #12  // See Code #01 for Alignment.  public static void Main()  {      Alignment[] alignments = (Alignment[])Enum.GetValues(typeof(Alignment));      Console.WriteLine("Wanna see the values of Alignment's menbers?");      foreach (Alignment a in alignments)          Console.WriteLine("{0:G} = {0:D}", a);  }   // Output:  // Wanna see the values of Alignment's menbers?  // Left = 0  // Center = 1  // Right = 2

--------------------------------------------------------------------------------

Q:如果我只需要其中某些枚举成员的值呢?

A:那么你可以把枚举转换为IConvertible接口,再调用对应的方法:

// Code #12  // See Code #01 for Alignment.  public static void Main()  {      IConvertible ic = (IConvertible)Alignment.Center;      int i = ic.ToInt32(null);      Console.WriteLine("The value of Alignment.Center is {0}.", i);  }   // Output:  // The value of Alignment.Center is 1.

--------------------------------------------------------------------------------

Q:为什么需要手动指定枚举成员的值?

A:一般情况下,使用默认的赋值规则就足够了,但某些情况下,为枚举成员指定一个与实际情况(模型)相符的值可能更有意义,这要视你具体所建的模型而定。

还是让我们来一个实际的例子:

// Code #13  public enum CustomerKind  {      Normal = 90,      Vip = 80,      SuperVip = 70,      InActive = 100  }   public class Customer  {      public readonly CustomerKind Kind;       private double m_Payment;      public double Payment      {          return m_Payment * (int)Kind / 100;      }       // Code here  }

我为枚举CustomerKind的每个成员都赋了一个特定的值,该值其实就是顾客购物折扣百分率。而在Customer类中,Payment属性就通过强类型转换来获取枚举成员的值(也就是购物折扣率),并用于货款计算。从这里可以看出,获取枚举成员的值还可以通过强类型转换方式。

--------------------------------------------------------------------------------

Q:既然枚举类型可以强制转换为整数,那么整数是否也可以强制转换为枚举类型?

A:答案是肯定的。

// Code #14  // See Code #01 for Alignment.  Alignment a = (Alignment)1;

但这种机制可能使你遇到一些麻烦:

// Code #15  // See Code #01 for Alignment.  class Program  {      static void Main()      {          Foo((Alignment)12345);      }       static void Foo(Alignment a)      {          // Code here      }  }

你无法避免有人进行这样的恶作剧!!

--------------------------------------------------------------------------------

Q:那么是否有办法对付这些恶作剧的人?

A:Sure!我们总不能假设人人都那么守规矩,所以,我们需要System.Enum的

public static bool IsDefined(Type enumType, object value);

现在我们把Code #15的Foo方法改进一下:

// Code #16  // See Code #01 for Alignment.  static void Foo(Alignment a)  {      if (!Enum.IsDefined(typeof(Alignment), a))          throw new ArgumentException("DO NOT MAKE MISCHIEF!");       // Code here  }

这样,恶作剧的人将会收到一个警告(异常消息)。当然,我们不排除有人是由于一时大意才造成这样的“恶作剧”,那么IsDefined方法同样可以帮助你处理好这些情况。

--------------------------------------------------------------------------------

Q:我认为我们还可以使用条件判断语句来处理这种情况:

// Code #17  // See Code #01 for Alignment.  static void Foo(Alignment a)  {      if (a != Alignment.Left &&          a != Alignment.Center &&          a != Alignment.Right)          throw new ArgumentException("DO NOT MAKE MISCHIEF!");       // Code here  }

或者

// Code #18  // See Code #01 for Alignment.  static void Foo(Alignment a)  {      switch(a)      {          case Alignment.Left:              Console.WriteLine("Cool~");              break;          case Alignment.Center:              Console.WriteLine("Well~");              break;          case Alignment.Right:              Console.WriteLine("Good~");              break;          default:              Console.WriteLine("DO NOT MAKE MISCHIEF!");              break;      }  }

A:你绝对可以这样做!事实上,如果你处于以下情况之一的话:

1. Alignment枚举代码不会被修改
2. 你不希望使用Alignment枚举新增的特性

那么我会推荐使用你的处理方式。而且,你还可以为自己的代码定义一个这样的方法:

// Code #19  // See Code #01 for Alignment.  public static bool IsAlignment(Alignment a)  {      switch(a)      {          case Alignment.Left:              return true;          case Alignment.Center:              return true;          case Alignment.Right:              return true;          default:              return false;      }  }

这个方法比起IsDefine方法高效多了。

感谢各位的阅读,以上就是“C#枚举赋值的方法是什么”的内容了,经过本文的学习后,相信大家对C#枚举赋值的方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI