iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何正确的在C#项目中使用枚举
  • 226
分享到

如何正确的在C#项目中使用枚举

2023-06-06 14:06:52 226人浏览 八月长安
摘要

本篇文章给大家分享的是有关如何正确的在C#项目中使用枚举,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。枚举基础枚举类型的作用是限制其变量只能从有限的选项中取值,这些选项(枚举类

本篇文章给大家分享的是有关如何正确的在C#项目中使用枚举,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

枚举基础

枚举类型的作用是限制其变量只能从有限的选项中取值,这些选项(枚举类型的成员)各自对应于一个数字,数字默认从 0 开始,并以此递增。例如:

public enum Days{ Sunday, Monday, Tuesday, // ...}

其中 Sunday 的值是 0,Monday 是 1,以此类推。为了一眼能看出每个成员代表的值,一般推荐显示地将成员值写出来,不要省略:

public enum Days{ Sunday = 0, Monday = 1, Tuesday = 2, // ...}

C# 枚举成员的类型默认是 int 类型,通过继承可以声明枚举成员为其它类型,比如:

public enum Days : byte{ Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7}

枚举类型一定是继承自 byte、sbyte、short、ushort、int、uint、long 和 ulong 中的一种,不能是其它类型。下面是几个枚举的常见用法(以上面的 Days 枚举为例):

// 枚举转字符串string foo = Days.Saturday.ToString(); // "Saturday"string foo = Enum.GetName(typeof(Days), 6); // "Saturday"// 字符串转枚举Enum.TryParse("Tuesday", out Days bar); // true, bar = Days.Tuesday(Days)Enum.Parse(typeof(Days), "Tuesday"); // Days.Tuesday// 枚举转数字byte foo = (byte)Days.Monday; // 1// 数字转枚举Days foo = (Days)2; // Days.Tuesday// 获取枚举所属的数字类型Type foo = Enum.GetUnderlyingType(typeof(Days))); // System.Byte// 获取所有的枚举成员Array foo = Enum.GetValues(typeof(MyEnum);// 获取所有枚举成员的字段名string[] foo = Enum.GetNames(typeof(Days));

另外,值得注意的是,枚举可能会得到非预期的值(值没有对应的成员)。比如:

Days d = (Days)21; // 不会报错Enum.IsDefined(typeof(Days), d); // false

即使枚举没有值为 0 的成员,它的默认值永远都是 0。

var z = default(Days); // 0

枚举可以通过 Description、Display 等特性来为成员添加有用的辅助信息,比如:

public enum apiStatus{ [Description("成功")] OK = 0, [Description("资源未找到")] NotFound = 2, [Description("拒绝访问")] AccessDenied = 3}static class EnumExtensions{ public static string GetDescription(this Enum val) {  var field = val.GetType().GetField(val.ToString());  var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));  if (customAttribute == null) { return val.ToString(); }  else { return ((DescriptionAttribute)customAttribute).Description; } }}static void Main(string[] args){ Console.WriteLine(ApiStatus.Ok.GetDescription()); // "成功"}

上面这些我认为已经包含了大部分我们日常用到的枚举知识了。下面我们继续回到文章开头说的用户角色存储问题。

用户角色存储问题

我们先定义一个枚举类型来表示两种用户角色:

public enum Roles{ Admin = 1, Member = 2}

这样,如果某个用户同时拥有 Admin 和 Member 两种角色,那么 User 表的 Roles 字段就应该存 3。那问题来了,此时若查询所有拥有 Admin 角色的用户的 sql 该怎么写呢?对于有基础的程序员来说,这个问题很简单,只要用位操作符逻辑与(‘&')来查询即可。

SELECT * FROM `User` WHERE `Roles` & 1 = 1;

同理,查询同时拥有这两种角色的用户,SQL 语句应该这么写:

SELECT * FROM `User` WHERE `Roles` & 3 = 3;

对这条 SQL 语句用 C# 来实现查询是这样的(为了简单,这里使用了 Dapper):

public class User{ public int Id { get; set; } public Roles Roles { get; set; }}connection.Query<User>( "SELECT * FROM `User` WHERE `Roles` & @roles = @roles;", new { roles = Roles.Admin | Roles.Member });

对应的,在 C# 中要判断用户是否拥有某个角色,可以这么判断:

// 方式一if ((user.Roles & Roles.Admin) == Roles.Admin){ // 做管理员可以做的事情}// 方式二if (user.Roles.HasFlag(Roles.Admin)){ // 做管理员可以做的事情}

同理,在 C# 中你可以对枚举进行任意位逻辑运算,比如要把角色从某个枚举变量中移除:

var foo = Roles.Admin | Roles.Member;var bar = foo & ~Roles.Admin;

这就解决了文章前面提到的用整型来存储多角色的问题,不论数据库还是 C# 语言,操作上都是可行的,而且也很方便灵活。

枚举的 Flags 特性

下面我们提供一个通过角色来查询用户的方法,并演示如何调用,如下:

public IEnumerable<User> GetUsersInRoles(Roles roles){ _logger.LogDebug(roles.ToString()); _connection.Query<User>(  "SELECT * FROM `User` WHERE `Roles` & @roles = @roles;",  new { roles });}// 调用_repository.GetUsersInRoles(Roles.Admin | Roles.Member);

Roles.Admin | Roles.Member 的值是 3,由于 Roles 枚举类型中并没有定义一个值为 3 的字段,所以在方法内 roles 参数显示的是 3。3 这个信息对于我们调试或打印日志很不友好。在方法内,我们并不知道这个 3 代表的是什么。为了解决这个问题,C# 枚举有个很有用的特性:FlagsAtrribute。

[Flags]public enum Roles{ Admin = 1, Member = 2}

加上这个 Flags 特性后,我们再来调试 GetUsersInRoles(Roles roles) 方法时,roles 参数的值就会显示为 Admin|Member 了。简单来说,加不加 Flags 的区别是:

var roles = Roles.Admin | Roles.Member;Console.WriteLing(roles.ToString()); // "3",没有 Flags 特性Console.WriteLing(roles.ToString()); // "Admin, Member",有 Flags 特性

给枚举加上 Flags 特性,我觉得应当视为 C# 编程的一种最佳实践,在定义枚举时尽量加上 Flags 特性。

解决枚举值冲突:2 的幂

到这,枚举类型 Roles 一切看上去没什么问题,但如果现在要增加一个角色:Mananger,会发生什么情况?按照数字值递增的规则,Manager 的值应当设为 3。

[Flags]public enum Roles{ Admin = 1, Member = 2, Manager = 3}

能不能把 Manager 的值设为 3?显然不能,因为 Admin 和 Member 进行位的或逻辑运算(即:Admin | Member) 的值也是 3,表示同时拥有这两种角色,这和 Manager 冲突了。那怎样设值才能避免冲突呢?既然是二进制逻辑运算“或”会和成员值产生冲突,那就利用逻辑运算或的规律来解决。我们知道“或”运算的逻辑是两边只要出现一个 1 结果就会 1,比如 1|1、1|0 结果都是 1,只有 0|0 的情况结果才是 0。那么我们就要避免任意两个值在相同的位置上出现 1。根据二进制满 2 进 1 的特点,只要保证枚举的各项值都是 2 的幂即可。比如:

  00000001
2:  00000010
4:  00000100
8:  00001000

再往后增加的话就是 16、32、64...,其中各值不论怎么相加都不会和成员的任一值冲突。这样问题就解决了,所以我们要这样定义 Roles 枚举的值:

[Flags]public enum Roles{ Admin = 1, Member = 2, Manager = 4, Operator = 8}

不过在定义值的时候要在心中小小计算一下,如果你想懒一点,可以用下面这种“位移”的方法来定义:

[Flags]public enum Roles{ Admin = 1 << 0, Member = 1 << 1, Manager = 1 << 2, Operator = 1 << 3}

一直往下递增编值即可,阅读体验好,也不容易编错。两种方式是等效的,常量位移的计算是在编译的时候进行的,所以相比不会有额外的开销。

以上就是如何正确的在C#项目中使用枚举,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网精选频道。

--结束END--

本文标题: 如何正确的在C#项目中使用枚举

本文链接: https://www.lsjlt.com/news/247300.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何正确的在C#项目中使用枚举
    本篇文章给大家分享的是有关如何正确的在C#项目中使用枚举,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。枚举基础枚举类型的作用是限制其变量只能从有限的选项中取值,这些选项(枚举类...
    99+
    2023-06-06
  • 枚举如何在java项目中使用
    今天就跟大家聊聊有关枚举如何在java项目中使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、枚举类型作为常量package myenum; public enum Color...
    99+
    2023-05-31
    java 枚举 ava
  • 一文教你正确的在java中使用枚举
    一文教你正确的在java中使用枚举?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java枚举使用详解在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而...
    99+
    2023-05-31
    java 枚举 ava
  • Go中怎么正确使用对枚举
    本篇内容主要讲解“Go中怎么正确使用对枚举”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go中怎么正确使用对枚举”吧!枚举是强类型编程语言中的一种类型,由一组名称和值组成。通常用来在编程语言中充...
    99+
    2023-06-15
  • 如何在Spring项目中正确使用Git?
    Spring是一个非常流行的Java框架,它帮助开发人员更快地构建Java应用程序。Git是一种分布式版本控制系统,它可以帮助开发人员更好地管理代码。在Spring项目中正确使用Git是非常重要的,本文将介绍如何在Spring项目中正确使用...
    99+
    2023-10-11
    apache spring git
  • 在Java项目中如何正确的使用LinkedList
    本篇文章给大家分享的是有关在Java项目中如何正确的使用LinkedList,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。LinkedList简介LinkedList 是一个继...
    99+
    2023-05-31
    java linkedlist ava
  • C++中的枚举如何使用
    这篇文章主要介绍了C++中的枚举如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++中的枚举如何使用文章都会有所收获,下面我们一起来看看吧。一、枚举是什么枚举(enumeration)类型用于存放用户指...
    99+
    2023-07-05
  • C# 枚举如何使用
    这篇文章主要介绍“C# 枚举如何使用”,在日常操作中,相信很多人在C# 枚举如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C# 枚举如何使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!为什么使用...
    99+
    2023-06-14
  • vue项目中如何添加枚举
    目录vue项目添加枚举在vue文件中引用使用方法vue中枚举的使用1. 建一个js文件如:common.js2. 在页面直接引入vue项目添加枚举 添加文件,文件名为enum.js ...
    99+
    2024-04-02
  • C++中enum枚举如何使用
    这篇文章将为大家详细讲解有关C++中enum枚举如何使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。C++ enum枚举格式:enum < 枚举类型名> {< 枚举表&g...
    99+
    2023-06-17
  • 正则表达式如何正确在Java项目中使用
    这篇文章将为大家详细讲解有关正则表达式如何正确在Java项目中使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.匹配验证-验证Email是否正确public static void ma...
    99+
    2023-05-31
    java 正则表达式 ava
  • 枚举如何在MyBatis中使用
    这篇文章给大家介绍枚举如何在MyBatis中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。具体方法如下:public enum ComputerState { OPEN(10), //开启 CLOSE(11),...
    99+
    2023-05-31
    mybatis 枚举
  • 在Java中如何使用枚举
    这篇文章给大家分享的是有关在Java中如何使用枚举的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。枚举类型(Enumerated Types) 让我们先看下面这一段小程序: enum Day {SUNDAY, MO...
    99+
    2023-06-03
  • lambda表达式如何正确的在Java8项目中使用
    这篇文章给大家介绍lambda表达式如何正确的在Java8项目中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。在Java8 里面Lambda是最火的主题,不仅仅是因为语法的改变,更重要的是带来了函数式编程的思想,我...
    99+
    2023-05-31
    java8 lambda ava
  • 如何在Spring项目中正确使用Go IDE的路径?
    Spring是一种非常流行的Java开发框架,它提供了丰富的功能和特性,使得开发人员可以快速地构建复杂的Web应用程序。当我们在Spring项目中使用Go IDE时,正确的路径配置是非常关键的。在本文中,我们将探讨如何在Spring项目中正...
    99+
    2023-10-06
    ide spring path
  • -classpath及路径如何正确的在Java项目中使用
    这期内容当中小编将会给大家带来有关-classpath及路径如何正确的在Java项目中使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。javac -classpath的使用:javac:如果当前你要编译...
    99+
    2023-05-31
    java classpath 路径
  • C#枚举中如何使用Flags特性
    这篇文章主要介绍了C#枚举中如何使用Flags特性,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。如果对一个值可以包含多个,那么可以使用枚举,加上Flags。新建一个Flags...
    99+
    2023-06-29
  • C语言的枚举如何使用
    这篇文章主要介绍“C语言的枚举如何使用”,在日常操作中,相信很多人在C语言的枚举如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言的枚举如何使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!概述...
    99+
    2023-06-30
  • 如何在C++中正确使用ostringstream
    在C++中,ostringstream 是一个输出流类,可以用于将数据转换为字符串。下面是一个示例,展示如何在C++中正确使用ost...
    99+
    2023-09-27
    C++
  • 在Java项目中使用枚举类型的方法有哪些
    这期内容当中小编将会给大家带来有关在Java项目中使用枚举类型的方法有哪些,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 Java枚举类型enum一、   通常定义常量方法我...
    99+
    2023-05-31
    java 枚举 ava
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作