enum,就是枚举类型,它是struct,int,single,double一样,都属于值类型,从ValueType类型中派生,存储在栈中。它在被创建时,不需要分配内在空间,所以对程序的性能是有好处的。

为啥要引入enum呢?一个原因,就是让程序更加安全,添加程序的可读性,提高开发的效率。

啥时用呢?当我们已经确定了变更的数量,功能时可以将变更一个个的枚举出来,这时用enum.

举个例子吧,有一个chart,它可以有三种类型显示方式,分别为line,bar和pie,用户可以随便去指定用哪种方式来显示,这时我们可以用变量来控制,也可以用类型更安全的枚举来控制,看吧。

namespace Constants
{
public class SystemConstant
{
public Constants.Webinfo ChartTypes { get; set; }
public string Result;
public string Create()
{
ChartTypes = Constants.Webinfo.Pie;
switch (ChartTypes)
{
case Constants.Webinfo.Bar:
Result = "bar"; // code statement //....... // ........
break;
case Constants.Webinfo.Line:
Result = "line";
break;
case Constants.Webinfo.Pie:
Result = "pie";
break;
}
return Result;
}
}
public enum Webinfo
{
Pie, Bar, Line
}
}

看到了吧,红色的地方就是我的enum了,在调用时,用Constants.Webinfo.Bar,Constants.Webinfo.Line,或者 Constants.Webinfo.Pie去调用,类型更安全,不会出现写错字符的现象。

Flags enum的高级用法:     NET中Flags枚举的使用
问题1 从指定 enum中去掉一个元素和加一个元素和判断某个元素是否在元素集合里存在:      看代码:

OrderState enums = OrderState.CustomerCanceled | OrderState.CustomerOrdered | OrderState.CustomerQuery; //必须是具体的枚举类型,不能直接写Enum类型
enums = enums ^ OrderState.CustomerCanceled; //第一种方法,如果集合里有这个元素,然后就移除这个元素,如果没有,就把这个元素加到集合里
enums = enums & (~OrderState.ShowBorder); // 第二种方法,移除一个元素
enums=enums | OrderState.CustomerOrdered; //向枚举列表中增加一个元素
bool hasFlag = ((enums & OrderState.CustomerCanceled) != ); //判断指定枚举元素是否在枚举列表中存在
Console.WriteLine(hasFlag);

问题2 将我们把复合的枚举集合以int类型存储在数据库中,然后我们怎么把这个int型的数值再转成一个枚举的组合呢?
    看代码:

       [Flags]
public enum Role
{
admini = ,
user = ,
backup = ,
guest = , }
Role enums2 = Role.admini | Role.user | Role.backup;
enums2 = enums2 | Role.guest;//加元素
enums2 = enums2 ^ Role.guest;//移除元素
Console.WriteLine(((int)enums2).ToString());//输出所包含的枚举元素的值的和
int RoleSum=(int)enums2) //结果是7 //结果RoleSum里是否包括Role.admin这个枚举值 ,
//方法一,bool aa = enums2.HasFlag(RoleName.Employee);
//查看指定元素
方法二:
if ( ((Role)Enum.Parse(typeof(Role), RoleSum.ToString()) & Role.admin) != ) // if ( ((Role)Enum.Parse(typeof(Role), RoleSum.ToString()) & Role.admin) == Role.admin)
Console.WriteLine("包含它");
else
Console.WriteLine("不包含它");
方法三:
[Flags]
public enum enumstatus
{
male = ,
female = ,
both = ,
}
enumstatus es;
es = enumstatus.male | enumstatus.female;
if ( (es & enumstatus.both) != )
Console.WriteLine("包含它" + es.ToString());
else
{
Console.WriteLine("不包含它");
}

问题3 如果向一个枚举集合中添加元素呢,我是说一个空的枚举对象中添加元素!

Role enums2 = Role.admini | Role.user | Role.backup; //方法一,这是静态赋值
Role enums2=new Role(); //方法二,这是先定义一个枚举对象,然后动态向里面加值
enums2 = enums2 | Role.admini; //也可以这样加
enums2 |= Role.backup; //也可以这样加
enums2 |= Role.user;

问题4 如何将一个枚举的集合转换为一个字符串数组对象,并将它进行输出
         
            /// <summary>
            /// 字符串数组化需要验证的枚举集合
            /// </summary>
            RoleName enums2=RoleName.Admin | RoleName.Boss | RoleName.HR | RoleName.DeptMgr;//为role赋多个值
            string[] enumNames = null;
            enumNames = Regex.Split(enums2.ToString(), ", ");
          
            if (enumNames.Length < 1)
            {
                new Exception("枚举的数量太少了!");
            }
            else
            {

foreach (var name in enumNames)
                {
                    Console.WriteLine(name);
                }
            }

Flags Enum的一些说明

 .NET中的枚举我们一般有两种用法,一是表示唯一的元素序列,例如一周里的各天;还有就是用来表示多种复合的状态。这个时候一般需要为枚举加上[Flags]特性标记为位域,例如:
[Flags] enum Styles{ ShowBorder = 1,         //是否显示边框ShowCaption = 2,        //是否显示标题ShowToolbox = 4         //是否显示工具箱} 
  这样我们就可以用"或"运算符组合多个状态,例如:
myControl.Style = Styles.ShowBorder | Styles.ShowCaption;  
  这时myControl.Style枚举的值将变成 1+2=3,它的ToString()将变成"Styles.ShowBorder , Styles.ShowCaption"
  这里我们可以解释为什么第三个值ShowToolbox可以为4,5..而不能为3。也就是说它的值不应该是前几项值的复合值。有一个比较简单的方法就是用2的n次方来依次为每一项赋值,例如 1,2,4,8,16,32,64.....
  现在举个常见的Flags应用例子。例如一个简单的权限系统,有"Admin"和"User"两种角色,我们可以在表中放一个 varchar()字段,以文本形式存放权限字"Admin,User"。但是用Flags型枚举的话,我们就可以直接将 Roles.Admin | Roles.User 的值放在一个int字段里。
  以下是关于枚举的一些常见操作:
  将枚举的值变回枚举对象:
  Styles style = (Styles) Enum.Parse(typeof(Styles), "4" );    // -> style = Styles.Toolbox;
  检查枚举是否包含某个元素:
  bool hasFlag = ((style & Styles.ShowBorder) != 0);
  其实我们还会碰到一种情况,就是需要从组合状态中去掉一个元素。用"^"运算符可以做到:
Styles style = Styles.ShowBorder | Styles.ShowCaption; style = style ^ Styles.ShowBorder; 
  这个时候style的值就会变成 Styles.ShowCaption
  但这里有一个很严重的问题(偶现在才发现)
  我们这个时候再执行一次
  style = style ^ Styles.ShowBorder;
  按照我们的设想,这个时候 style 的值是 Styles.ShowCaption,不包含 Styles.ShowBorder,所以我们就算去掉这个元素,style应该还是不会变。但实际的 style 的值却又变成了 Styles.ShowBorder | Styles.ShowCaption !! 再执行一遍,又会去掉这个元素,周而复始。
  当然我们可以在去掉某个元素前做一番检查,如果枚举包含这个元素,再去掉它:
if ((style & Styles.ShowBorder) != 0){     style = style ^ Styles.ShowBorder; } 
  不知道有没有其它方法可以方便地从Flags枚举状态中去掉一个元素。。
  Thanks to mobilebilly:
  style = style & (~Styles.ShowBorder) 可以方便去掉一个元素。
好好利用枚举
      这段时间手里有个有关订单的项目,订单一般有个状态的,以前很多要时候都会想到订单的状态就那几个种,就把它写死吧,不用一个数据库表了,太浪费资源了,但写死了用一个数字来代表一种订单状态,这样在编码时还要记得什么数字代码什么状态,如果不小心把它写错了,会导致数据出错。
      后来想到.NET有个枚举,这么好的东西为何不用上来呢,这不但可以方便以后的代码维护,也方便编码。

public enum OrderState
{
/**//// <summary>
/// 无效状态
/// </summary>
Invalid = ,
/**//// <summary>
/// 客户询价
/// </summary>
CustomerQuery = ,
/**//// <summary>
/// 客户落单
/// </summary>
CustomerOrdered = ,
/**//// <summary>
/// 客户付款
/// </summary>
ReceiverCustomerPayment = ,
/**//// <summary>
/// 向供货商订货
/// </summary>
SupplierOrdered = ,
/**//// <summary>
/// 供货商确认货期
/// </summary>
SupplierOrderTerm = ,
/**//// <summary>
/// 收到货品
/// </summary>
RecieverGoods = ,
/**//// <summary>
/// 客户取消订单
/// </summary>
CustomerCanceled = ,
/**//// <summary>
/// 供货商取消订单
/// </summary>
SupplierCancelded =
}
//使用我们的枚举组合,在一个字段存储所有的操作权限,但值只为一个数
[Flags]//必须打上一个标记,打上这个标记系统才能识别这个枚举可使用组合方式
public enum Role
{
/*
* Role枚举的定义值的规律,0到1,1到2,2到4,4到8,8到16......当前的值为上个值的2次方,为什么要这样定义呢?
* 是因为任何的组合都可以在枚举范围中某几个值的总和,例如组合值为15,那15就等于枚举定义范围里的定义值为1、2、4、8相加,
* 15=1+2+4+8。只有按规律定义值,就可以组合成任意数。
* 组合必须注意的几点:
* 1.枚举定义时,必须打上[Flags]标记,系统才会根据这个标记来决定这个枚举是否可组合使用
* 2.定义枚举的值必须按以上所说的规律定义,例如:0、1、2、4、8、16、32.......也可以使用3次方的方式,例如:0、3、6、12、24..........
* OrderState enums = OrderState.CustomerCanceled | OrderState.CustomerOrdered | OrderState.CustomerQuery; //必须是具体的枚举类型,不能直接写Enum类型
* enums = enums ^ OrderState.CustomerCanceled; //第一种方法,如果集合里有这个元素,然后就移除这个元素,如果没有,就把这个元素加到集合里
* enums = enums & (~OrderState.ShowBorder); // 第二种方法,移除一个元素
* enums=enums | OrderState.CustomerOrdered; //向枚举列表中增加一个元素
* bool hasFlag = ((enums & OrderState.CustomerCanceled) != 0); //判断指定枚举元素是否在枚举列表中存在
* Console.WriteLine(hasFlag);
*/ 未分配 = ,
删除数据 = ,
修改数据 = ,
新增数据 = ,
查看数据 = ,
} public enum Sex
{
女 = ,
男 = ,
} //
// GET: /Task/Enum/ public ActionResult Index()
{
//获取枚举对应的值
int enumValue = (int)Sex.男; //enumValue的值则为 1 //获取枚举的名称
string enumText = Sex.男.ToString(); //enumText的值则为 男
//将int类型值转换为对应的枚举
int intValue = ;
Sex sex = (Sex)intValue; //sex则为对应男的枚举 //将名称转换为对应的枚举
string strValue = "男";
sex = (Sex)Enum.Parse(typeof(Sex), strValue); //判断int值或名称是否在枚举定义项类
if (Enum.IsDefined(typeof(Sex), intValue)) //第二个参数也可以传入strValue
{
//you
} switch (sex)
{
case Sex.女: break;
case Sex.男: break;
default:
break;
} //如果用户有删除、修改的权限在枚举定义中只有1和2的枚举,那怎么将这两个枚举值组合成一个枚举值存储到数据库呢?
int allRole = (int)Role.删除数据 + (int)Role.修改数据; //这时allRole的值为3 (两个枚举对应值相加:1+2=3),这时直接将allRole值存储到数据就可以了
//判断用户是否具有某个操作权限,先从数据库中取出权限值,以上述,allRole则为数据库中取出的值,为3,接下来我们通过位算符来判断
Role myAllRole = (Role)allRole;//将int值强制转换为枚举 //此时,myAllRole的名称为'删除数据, 修改数据' ,值为3
//判断是否有删除权限
if ((myAllRole & Role.删除数据) == Role.删除数据)
{
//you
}
/*
* Role枚举的定义值的规律,0到1,1到2,2到4,4到8,8到16......当前的值为上个值的2次方,为什么要这样定义呢?
* 是因为任何的组合都可以在枚举范围中某几个值的总和,例如组合值为15,那15就等于枚举定义范围里的定义值为1、2、4、8相加,
* 15=1+2+4+8。只有按规律定义值,就可以组合成任意数。
* 组合必须注意的几点:
* 1.枚举定义时,必须打上[Flags]标记,系统才会根据这个标记来决定这个枚举是否可组合使用
* 2.定义枚举的值必须按以上所说的规律定义,例如:0、1、2、4、8、16、32.......也可以使用3次方的方式,例如:0、3、6、12、24..........
*/ return View();
}

http://www.cnblogs.com/lori/archive/2010/03/17/1688133.html

说说C#中的enum吧的更多相关文章

  1. 关于Java中枚举Enum的深入剖析

    在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定.Java也不例外.Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析. 什么是Enum Enum是自Java ...

  2. 深入掌握Java中的enum

    对于要在程序中要表示有限种类的某事物,一般我们可以采用两种方式,一是使用:public static final String 常量:二是使用enum来表示.一般而言前者简单,但是不能够很好的提供更多 ...

  3. Python中模拟enum枚举类型的5种方法分享

    这篇文章主要介绍了Python中模拟enum枚举类型的5种方法分享,本文直接给出实现代码,需要的朋友可以参考下   以下几种方法来模拟enum:(感觉方法一简单实用) 复制代码代码如下: # way1 ...

  4. 引用类中的enum

    引用类中的enum 引用类中的enum,需要加类的域class_name::value_in_enum_name 点击(此处)折叠或打开 #include <stdio.h> #inclu ...

  5. @清晰掉 C++ 中的 enum 结构在内存中是怎么存储的?

     C++ 中的 enum 结构在内存中是怎么存储的? C++ C++ 中的 enum 结构在内存中是怎么存储的?里面存储的是常量值吗?   关于占用内存的大小,enum类型本身是不占内存的,编译器直接 ...

  6. 如何使用Java中的Enum类

    Java1.5 中出现了枚举类型.当一个值都在一个固定的范围内变化,那就可以使用 enum 类型来定义.比如说,一周有七天,一年有四季. 没有枚举类的时候,我们用常量来定义一组范围值的: public ...

  7. MVC3不能正确识别JSON中的Enum枚举值

    一.背景 在MVC3项目里,如果Action的参数中有Enum枚举作为对象属性的话,使用POST方法提交过来的JSON数据中的枚举值却无法正确被识别对应的枚举值. 二.Demo演示 为了说明问题,我使 ...

  8. Java中的Enum的使用与分析

    使用name()方法和valueOf(String)方法可以在枚举类型对象和字符串之间方便得转换.如果valueOf(String)方法的参数不是该枚举类型合法的字符串,则会抛出IllegalArgu ...

  9. Java中的Enum枚举类型总结

    废话不多说,直接上代码,该例子来源于:http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html public enum Planet { ...

  10. C++中typedef enum 和 enum

    在C++中,这两种定义枚举类型的关键字用法和效果相同,推荐使用前者.typedef enum多用在C语言中. 在C语言中,如果使用typedef enum定义一个枚举类型,比如: typedef en ...

随机推荐

  1. Linux查看并修改mysql的编码

    系统:阿里云 一.查看mysql字符集 输入:show variables like 'character_set_%'; 二.修改某一个数据库的编码 输入:alter database dbname ...

  2. Java进阶之美文共享

    2.在Java中如何避免"!=null"式的判空语句?  3.Java问答:终极父类(3)  Java问答:终极父类(下) Java问答:终极父类(上) 内存不足:杀死进程还是牺牲 ...

  3. mongodb切换到admin

    127.0.0.1:后面是端口,/admin是切换到管理员权限 cd C:\Program Files\MongoDB\Server\3.0\bin mongo.exe 127.0.0.1:27017 ...

  4. 《精通Spring4.X企业应用开发实战》读后感第五章(通过编码方式动态添加Bean)

  5. p3201&bzoj1483 梦幻布丁

    传送门(洛谷) 传送门(bzoj) 题目 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜 ...

  6. cf834D(dp+线段树区间最值,区间更新)

    题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...

  7. bzoj1010 玩具装箱

    玩具装箱 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  8. 洛谷P4332 [SHOI2014]三叉神经树(LCT)

    传送门 FlashHu大佬太强啦%%% 首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权 先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点 ...

  9. Docker存储卷

    六.Docker 存储卷(volume) COW:写时复制 Bind mount volume:手动mount绑定的卷 # docker run --name centos-3 -it -v /dat ...

  10. php路径问题

    ./ 是在当前目录开始寻找文件/ 是在下一级目录开始寻找文件 ../ 这个是在上一级目录开始寻找文件 $_SERVER['DOCUMENT_ROOT']获取站点根目录 __FILE__获取当前文件的完 ...