关于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的声明:
None.gif 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
ExpandedBlockStart.gifContractedBlock.gif  
dot.gif{
InBlock.gif      Left,    
// 0
InBlock.gif
      Center,    // 1
InBlock.gif
      Right    // 2
ExpandedBlockEnd.gif
  }

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

public enum CustomerKind
ExpandedBlockStart.gifContractedBlock.gif  
dot.gif{
InBlock.gif      Normal 
= 90,
InBlock.gif      Vip 
= 80,
InBlock.gif      SuperVip 
= 70,
InBlock.gif      InActive 
= 100
ExpandedBlockEnd.gif  }

None.gif
None.gif  
public class Customer
ExpandedBlockStart.gifContractedBlock.gif  
dot.gif{
InBlock.gif      
public readonly CustomerKind Kind;
InBlock.gif
InBlock.gif      
private double m_Payment;
InBlock.gif      
public double Payment
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif          
return m_Payment * (int)Kind / 100;
ExpandedSubBlockEnd.gif      }

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

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


ExpandedBlockEnd.gif  }


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

 static void Main()
ExpandedBlockStart.gifContractedBlock.gif  
dot.gif{
InBlock.gif      Alignment a = Alignment.Right;
InBlock.gif      Console.WriteLine("Alignment is {0}.", a.ToString());
InBlock.gif
InBlock.gif      FontStyle fs = FontStyle.Bold | FontStyle.Underline;
InBlock.gif      Console.WriteLine("FontStyle is {0}.", fs.ToString());
ExpandedBlockEnd.gif  }

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

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

static
 void
 Main()
ExpandedBlockStart.gifContractedBlock.gif  
dot.gif
{
InBlock.gif      
string
 name = "Right";
InBlock.gif      Alignment a = (Alignment)Enum.Parse(
typeof(Alignment), name, false
);
InBlock.gif
InBlock.gif      Console.WriteLine(a.ToString());
InBlock.gif
InBlock.gif      
string
 names = "Bold, Italic, Underline";
InBlock.gif      FontStyle fs = (FontStyle)Enum.Parse(
typeof(FontStyle), names, false
);
InBlock.gif
InBlock.gif      Console.WriteLine(fs.ToString());
ExpandedBlockEnd.gif  }

不应该使用枚举的情况:None.gif
枚举类型表达了一种稳定的分类标准。当你查看.NET Framework BCL中的枚举类型,你会发现它们几乎没有任何改变的可能或者趋势,表现出一种稳定性。所以,当你所要表达的分类标准也同样具备这种稳定性时,你就可以考虑枚举类型了。那么什么情况下不使用枚举呢?一般说来,当分类标准不闭合时——即新的子分类随时有可能产生或者现有子分类随时有可能被替换——你就应该考虑使用其他的方式来表达了.
目录
相关文章
|
1月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
1月前
|
C#
C#学习相关系列之数据类型类的三大特性(二)
C#学习相关系列之数据类型类的三大特性(二)
|
1月前
|
C#
C#学习相关系列之yield和return的区别
C#学习相关系列之yield和return的区别
|
1月前
|
C#
C#学习相关系列之数组---常用方法使用(二)
C#学习相关系列之数组---常用方法使用(二)
|
1月前
|
存储 C#
C#学习系列相关之数组(一)---数组的定义与使用
C#学习系列相关之数组(一)---数组的定义与使用
|
30天前
|
C#
C#的基本语法结构学习
【5月更文挑战第17天】C#基础语法包括变量(如`int x = 10`)、常量(`const int MAX_VALUE = 100`)、运算符(如算术和比较运算符)、控制语句(if、for、while等)和函数声明(`int Add(int x, int y) { return x + y; }`)。这些构成C#程序的基本元素。
45 0
|
1月前
|
开发框架 .NET C#
C#学习相关系列之Linq用法---where和select用法(二)
C#学习相关系列之Linq用法---where和select用法(二)
|
12天前
|
前端开发 Java C#
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
|
21天前
|
安全 API C#
C#.Net筑基-类型系统②常见类型--枚举Enum
枚举(enum)是C#中的一种值类型,用于创建一组命名的整数常量。它们基于整数类型(如int、byte等),默认为int。枚举成员可指定值,未指定则从0开始自动递增。默认值为0。枚举可以与整数类型互相转换,并可通过`[Flags]`特性表示位域,支持位操作,用于多选场景。`System.Enum`类提供了如`HasFlag`、`GetName`等方法进行枚举操作。
|
30天前
|
C#
C#的类和对象的概念学习案例刨析
【5月更文挑战第17天】C#是一种面向对象的语言,以类和对象为核心。类作为对象的模板,定义了属性(如Name, Age)和行为(如Greet)。对象是类的实例,可设置属性值。封装通过访问修饰符隐藏实现细节,如Customer类的私有name字段通过Name属性访问。继承允许新类(如Employee)从现有类(Person)继承并扩展。多态让不同对象(如Circle, Square)共享相同接口(Shape),实现抽象方法Area,提供灵活的代码设计。
40 1