关于c# 枚举 enum 的学习

从长远来看,创建枚举可以节省大量的时间,减少许多麻烦。使用枚举比使用无格式的整数至少有如下三个优势:

●       枚举可以使代码更易于维护,有助于确保给变量指定合法的、期望的值。

●       枚举使代码更清晰,允许用描述性的名称表示整数值,而不是用含义模糊的数来表示。

●       枚举使代码更易于键入。在给枚举类型的实例赋值时,VS.NET IDE会通过IntelliSense弹出一个包含可接受值的列表框,减少了按键次数,并能够让我们回忆起可能的值。

public enum FileStates{Begin=1,Pause=2,RollBack=3,Success=4};
枚举类型都是值类型。System.Enum是一个抽象类(abstract class),所有枚举类型都直接继承自它,当然也同时继承了它的所有成员。所有的值类型都是System.ValueType的后代,枚举类型也不例外,枚举类型直接继承自System.Enum,而System.Enum却又直接继承自System.ValueType的,所以,枚举类型也是System.ValueType的后代。
值类型都是System.ValueType的后代”,但System.ValueType的后代不全是值类型,System.Enum就是唯一的特例!在System.ValueType的所有后代中,除了System.Enum之外其它都是值类型。事实上,我们可以在.NET的源代码中找到System.Enum的声明:

public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible

  • 1. 所有枚举类型(enum type)都是值类型。
  • 2. System.Enum和System.ValueType本身是引用类型。
  • 3. 枚举类型(enum type)都是隐式的直接继承自System.Enum,并且这种继承关系只能由编译器自动展开。但System.Enum本身不是枚举类型(enum type)。
  • 4. System.Enum是一个特例,它直接继承自System.ValueType,但本身却是一个引用类型。

A:枚举类型可以被装箱成System.Enum、System.ValueType、System.Object或者System.IConvertible、System.IFormattable、System.IComparable。

注意:在.NET 1.1上,枚举类型只能被装箱到System.Enum、System.ValueType、System.Object;而在.NET 2.0上,枚举类型还能被装箱到System.Enum所实现的三个接口:System.IConvertible、System.IComparable、System.IFormattable。对应的装箱操作既可以为隐式的也可以是显式的。

枚举类型与整数类型有一定的关系。事实上,每一个枚举类型都有与之相对应的整数类型,我们称该整数类型为底层类型(underlying type),默认的情况下使用,.NET使用System.Int32。当然,你可以手动将其指定为其他的整数类型:
能被指定为枚举的底层类型的只能是如下所列的整数类型:byte, sbyte, short, ushort, int, uint, long, ulong。

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

那么被赋值的成员的值就是你所指定的值。当然,无论你是否手动指定枚举成员的值,递增步长都不会变,总是为1。为了测试你是否理解,请说出下面枚举个成员的值以及你的判断理由(请用人脑而不是电脑来运行以下代码):
public enum DriveType : sbyte
  {
      CDRom,
      Fixed = -2,
      Network,
      NoRootDirectory = -1,
      Ram,
      Removable = Network * NoRootDirectory,
      Unknown
  }

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;
      }

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

      // Code here
  }

枚举类型可以强制转换为整数,整数也可以强制转换为枚举类型
Alignment a = (Alignment)1;但这种机制可能使你遇到一些麻烦
public static bool IsAlignment(Alignment a)
  {
      switch(a)
       {
    case Alignment.Left:
    case Alignment.Center:
    case Alignment.Right:
      return true;
    default:
      return false;
      }

  }

枚举类型转换(解析)成字符串类型
最简单的方法就是使用System.Enum的public override string ToString();  或者把枚举类型转换为IConvertible接口,再调用该接口的string ToString(IFormatProvider provider);

 static void Main()
  {
      Alignment a = Alignment.Right;
      Console.WriteLine("Alignment is {0}.", a.ToString());

      FontStyle fs = FontStyle.Bold | FontStyle.Underline;
      Console.WriteLine("FontStyle is {0}.", fs.ToString());
  }

手动指定格式参数:Console.WriteLine("Alignment is {0}.", a.ToString("d"));

一个表示枚举成员的字符串,如何将其解析为对应枚举类型:
这时你就需要System.Enum的public static object Parse(  Type enumType, string value,  bool ignoreCase  );

static void Main()
  {
      string name = "Right";
      Alignment a = (Alignment)Enum.Parse(typeof(Alignment), name, false);

      Console.WriteLine(a.ToString());

      string names = "Bold, Italic, Underline";
      FontStyle fs = (FontStyle)Enum.Parse(typeof(FontStyle), names, false);

      Console.WriteLine(fs.ToString());
  }

不应该使用枚举的情况:
枚举类型表达了一种稳定的分类标准。当你查看.NET Framework BCL中的枚举类型,你会发现它们几乎没有任何改变的可能或者趋势,表现出一种稳定性。所以,当你所要表达的分类标准也同样具备这种稳定性时,你就可以考虑枚举类型了。那么什么情况下不使用枚举呢?一般说来,当分类标准不闭合时——即新的子分类随时有可能产生或者现有子分类随时有可能被替换——你就应该考虑使用其他的方式来表达了.

时间: 2024-08-18 06:34:07

关于c# 枚举 enum 的学习的相关文章

枚举Enum的用法

一.前言 对于枚举Enum,大家都非常熟悉,但枚举出现的场景非常多的时候,是不是可以抽象出一个通用的解决方式.代码大家都会写,但并不是所有人都喜欢写重复的代码,老是用Ctrl+C和Ctrl+V累不累啊?很多人和我一样,非常不喜欢写重复的代码,代码写多了,BUG就多.对于常见的场景,大部分人都喜欢抽象出来,写一套通用的,每个地方都可以用,而且不易出错.当然,你喜欢Ctrl+C和Ctrl+V,本人也没有办法.... 二.int值,string值转换成Enum 如下,一个简单枚举: public en

结构体struct、枚举enum、联合体union、位字段、自定义类型typedef、字节对齐

结构体struct 1 结构体的基本知识 2 结构体与函数 3 结构体数组 4 自引用结构体 枚举变量enum 联合体union 位字段 1 一般的方法定义屏蔽吗 2 用位字段来定义屏蔽吗 自定义类型typedef 字节对齐 pragma pachx 按x个字节对齐 1.结构体struct 1.1 结构体的基本知识 #include <stdio.h> struct point{ int x; int y; }p1, p2, p3; struct point pt; struct point

java中的枚举enum,如何实现

问题描述 java中的枚举enum,如何实现 这两天在想java中的枚举,不是很明白,java中的枚举除自身的枚举成员外,还可以实现接口,可以有构造函数及可以定义方法. c#中的枚举简简单单的值类型,而java中的枚举是引用类型. 在c#项目中,经常用枚举, public enum FileType { Unknow=0 Word=1 Excel=2 } public T NumToEnum(int number) { try { if (Enum.IsDefined(typeof(T) num

深入谈谈java的枚举(enum)类型_java

前言 在大家日常编程中,往往存在着这样的"数据集",它们的数值在程序中是稳定的,而且"数据集"中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的"数据集",春夏秋冬四个数据元素组成了四季的"数据集".在java中如何更好的使用这些"数据集"呢?因此枚举便派上了用场 枚举其实就是一种类型,跟int, char 这种差不多,就是定义变量时限制输入的,你只能够赋enum里面规定的值. 枚举(enum)实

C++基础教程(三)——枚举enum

//============================================================================ // Name : Enum.cpp // Author : lf // Version :<C++语言基础教程> 吕凤翥 P33--P35 // Copyright : Your copyright notice // Description : 枚举enum基础知识 //================================

Java枚举(enum) 详解7种常见的用法_java

JDK1.5引入了新的类型--枚举.在 Java 中它虽然算个"小"功能,却给我的开发带来了"大"方便.  用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. public enum Color { RED, GREEN, BLANK, YELLOW } 用法二:switch JDK1.6之前的switch语句只支持int

Jsdk5.0中新增枚举enum类型使用例解

js 作者:Junsan Jin 日期:2005-03-25 邮箱:junsan21@126.com ; junnef21@sohu.com Jsdk5.0中新增了很多的特性,如泛型.增强的循环.改进的装.拆箱.静态引入等,大大增强了java语言的易用性. 我现在正在做一个从com+(dcom)平台到j2ee平台移植的项目,中间有很多枚举类型的定义,以前做起来要引入第三方类库,或者自己写类库,或者干脆定义成静态变量使用,很不方便,而且可能会产生很多问题.Jsdk5.0的发布正好解决了这些问题.

再谈java枚举 ENUM

没有枚举之前: 在没有枚举之前,我们想列举一些相关的常量,我们会采用如下的方式: 1 2 3 4 interface ActionInterface {     public static final int RIGHT = 0;     public static final int LEFT = 1; } 然后在某个类似于下面的方法中,使用这些常量: 1 2 3 4 5 6 7 8 9 10 11 12 public void playWithInterface(int num) {    

马士兵J2SE-第六章-常用类-String类、StringBuffer类、枚举ENUM

  public class test { public static void main(String[] args) { String s1="hello"; String s2="world"; String s3="hello"; System.out.println(s1==s3); s1=new String("hello"); s2=new String("hello"); System.ou