当前位置: 首页 > news >正文

C#参考 : 枚举类型

 一、 关于 类型

     再具体学习枚举类型之前,先了解一下C#的类型。

     (1)值类型

           (a)变量可以直接包含它们自己的数据;如 int i = 35;

           (b)局部变量总是放在栈(stack)中。

·    (2)引用类型

            (a)变量间接指向它们的数据;

            (b)局部变量指向堆(heap)中的对象.

 

 

 


 

 

 

        枚举(enum)         值类型

结构(struct)        值类型

类(class)            引用类型

接口(interface)    引用类型

数组([ ]array )     引用类型

委托(delegate)     引用类型

 

 

 


 

 

     关于两者的区别可以参考文章:C#参考 : 值类型和引用类型的区别 (深入详解)

 

     也许,你对上面的例子感到一点点奇怪,c#中的那些内在类型如int,double怎么没有。这是因为:C#规定这些内在类属于结构,C#称之为简单类型。简单类型和用户自定义类型之间的最大区别是前者可以有字面表达式(如42),而后者没有。

     当然,还有第三种类型:指针。但指针只用在由unsafe关键字标识的非安全的代码中。

     二、枚举类型

它是一个用户声明的值类型

enum  Suit
{
    Clubs, 
    Diamonds, 
    Hearts, 
    Spades
}

 

//Suit表示一副牌,它有4个花色:梅花(Clubs),方块(Diamonds),红心(Hearts),//黑桃(Spades)

sealed class  Example
{
    
static void  Main()
    {
        dot.gif

        Suit lead 
= Spades; //错误

        dot.gif

        Suit trumps 
= Suit.Clubs; //正确

        dot.gif
    }
}

 

枚举的声明可以出现在类声明的相同地方。

枚举的声明包括名字、访问权限、内在的类型和枚举的成员。

枚举中声明的常量的范围是定义它们的枚举,换言之,下面的例子是错误的:

              Suit trumps = Clubs;

Clubs必须被限制为Suit的一个成员,就如下面:

       Suit trumps = Suit.Clubs;

三、枚举的注意点

·       枚举值缺省为int; 你可以选择任一内在的整数类型,但不可以是字符类型.

enum Suit : int   //内在类型是int,可以省略
{
    Clubs,
    Diamonds,
    Hearts 
= 42,  //成员的取值缺省为前一个成员取值+1,但可以自己赋初值
     Spades,       //最后一个分号是可选的
 };//可以有结尾分号

 

1). 枚举类可以显式的声明它的内在类型是sbyte, byte, short, ushort, int, uint, long, ulong。如果一个枚举类没有显式声明它的内在类型,则缺省为int。

2). 成员的取值必须和枚举声明的内在类型相同,并且必须在内在类型的范围之内(例如,你不能让成员的取值为负数,而枚举的内在类型准确的说是uint)。

3). 如果成员没有被赋值, 那么它的取值是前一个成员取值+1,第一个成员的缺省值是1。枚举的成员的取值可以有相同的取值。

4). 最后一个枚举成员可以使用一个结尾分号,这使得你将来可以很方便地加入更多的成员。

5). 枚举成员的访问权限隐含为public。

四、枚举类型应用详解

(1)优先考虑使用枚举,而不是类的静态常量。

比如:

public static class  Day
{
    
public static int Sun = 1 ;
    
public static int Mon = 2 ;
    
public static int Tue = 3 ;
    
//dot.gif
}

应该使用如下的枚举:

enum  Day 

    Sun 
= 1
    Mon, 
    Tue, 
    Wed, 
    Thu, 
    Fri, 
    Sat 
};

 

(2)如果参数、返回值、变量等类型可以是枚举,则不要使用其它基础类型。

比如:
Range r = Range.MAX;     //好
int r = (int)Range.MAX;    //不好

        (3)枚举命名

枚举一般使用名词或名词组合,简单枚举使用单数,标志枚举使用复数。

(4)大多数情况下不需要更改枚举的默认类型

        也就是说大多数情况下,使用 int(System.Int32)作为枚举类型。除非:

  • 枚举是标志枚举,且标志多于 32 个(此时 int 类型装不下)。
  • 枚举被非常大量且频繁地使用,为了节约空间使用小于 int 的类型。
  • 不得不使用其它类型的情况。

(5)不要在枚举中设置“哨兵”

我们可能觉得在枚举的两端加上哨兵,这样在判断一个数是否在枚举中时,只需要判断是否在哨兵之中。非常不幸,我们不应该这么做,这破坏了枚举的意义。

        enum Day { FirstValue, Sun, Mon, Tue, Wed, Thu, Fri, Sat , LastValue };     //FirstValue、LastValue 应该去掉
  • 简单枚举包含的值不用于组合,也不用于按位比较。
  • 标志枚举应使用按位 OR 操作进行组合。

(6)简单枚举

前面提到的 Day、Range 都可以称之为简单枚举,因为不能将他们各自的值组合起来。

(7)标志枚举

标志枚举的设计有两点要注意。

  • 指明 FlagsAttribute,以指示可以将枚举作为位域(即一组标志)处理。
  • 枚举中各标志的值应该是以 2 的幂来赋值,即:1、2、4、8、16、32……

举个例子,假如我们在设计 Windows 窗口程序,窗口有最小化、最大化、关闭按钮,我们想任意组合显示,也就是说我们可以显示其中的任意 0 个或一个或多个按钮。

如果使用简单枚举,按照排列组合,就存在8中情况,那么要使用8个枚举数,如果这里不是三个按钮,而是四个按钮,枚举数就更多了。所以这样不现实。

为什么这里使用简单枚举不现实呢?因为简单枚举不能组合,采用标志枚举就可以轻松解决了。

[Flags]
public enum  WindowStyle
{
    MINIMUM_BUTTON 
= 1//十六进制表示为 0x0001
    MAXIMUM_BUTTON = 2 ,
    CLOSE_BUTTON 
= 4
}

我们在设置窗口样式时,利用 'OR' 自由组合:

WindowStyle ws = WindowStyle.MINIMUM_BUTTON | WindowStyle.CLOSE_BUTTON; 

//表示既有 MINIMUM_BUTTON 也有 CLOSE_BUTTON

这就是为什么标志的值要按 2 的幂排列的原因了,也是为什么标志多于 32 个时不能使用 int 类型的原因了。

通常我们为常用的标志组合提供特殊的枚举值

仍然以上述窗口为例,可知大多数情况下,我们均要显示这三个按钮,所以每次使用时都要用:

WindowStyle ws = WindowStyle.MINIMUM_BUTTON | MAXIMUM_BUTTON | WindowStyle.CLOSE_BUTTON;

实在有些繁琐,我们可以修改枚举为如下:

[Flags]
public enum  WindowStyle
{
    MINIMUM_BUTTON 
= 1 ,
    MAXIMUM_BUTTON 
= 2 ,
    CLOSE_BUTTON 
= 4 ,
    ALL_BUTTON 
= 7
}

增加一个 ALL_BUTTON 为前三个标志的值。使用时直接用 ALL_BUTTON 就可以了。

转载于:https://www.cnblogs.com/30ErLi/archive/2010/09/15/1826601.html

相关文章:

  • CPA广告最适合哪些产品推广?
  • 根据条件获取json(无限级)中指定的对象
  • ASP.NET中JavaScript 调用后台事件和方法
  • WF4.0中如何将C#流程装换成XAML流程
  • 故宫的定位
  • 实验五、路由器广域网HDLC 封装配置
  • 熬夜人必看
  • 爱立信:用什么保持全球老大的地位?
  • 升级了Windows Live Essentials 2011,赞
  • [程序安装包制作] Advanced Installer 备忘
  • DR与主/从路由器的区别
  • Linq to entity 中 实现 Sql 中的like 的两个方法小解
  • DIV垂直居中的各种方法
  • unicode变形一句话突破web防火墙过滤
  • Silverlight for Windows Phone Toolkit升级 新增四个控件
  • conda常用的命令
  • Druid 在有赞的实践
  • idea + plantuml 画流程图
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • MYSQL 的 IF 函数
  • Nacos系列:Nacos的Java SDK使用
  • Shadow DOM 内部构造及如何构建独立组件
  • win10下安装mysql5.7
  • 记一次和乔布斯合作最难忘的经历
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 聊聊hikari连接池的leakDetectionThreshold
  • 前端之Sass/Scss实战笔记
  • 微信小程序:实现悬浮返回和分享按钮
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • const的用法,特别是用在函数前面与后面的区别
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • 整理一些计算机基础知识!
  • ​2021半年盘点,不想你错过的重磅新书
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (LeetCode C++)盛最多水的容器
  • (pytorch进阶之路)扩散概率模型
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .Net 路由处理厉害了
  • .NET 依赖注入和配置系统
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .net反混淆脱壳工具de4dot的使用
  • .NET中两种OCR方式对比
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • [] 与 [[]], -gt 与 > 的比较
  • []Telit UC864E 拨号上网
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——
  • [⑧ADRV902x]: Digital Pre-Distortion (DPD)学习笔记
  • [bzoj1324]Exca王者之剑_最小割
  • [C/C++] C/C++中数字与字符串之间的转换