C#,入门教程(66)——枚举Enum的高等用法

前言:国内码农与国外优秀程序员的最大区别是,我们的专家、教授喜欢唾沫横飞地,夸夸其谈语言特性、框架、性能,唯一目的是带私货(书籍或教程),很少能写出真有用的程序。差距在哪呢?基础!基础!基础!

1 优缺点共存是所有语言、语法的常态

枚举enum是常用的数据类型,有很多优点。

枚举使用过程也有很多不便,比如:值、名字、描述的对应关系不便检索。

2 高级一点的使用方法

下面的代码具有较高的参考价值,建议仔细阅读。 

using System;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;

/// <summary>
/// 便于使用的枚举
/// </summary>
namespace K50018.Kernal
{
    /// <summary>
    /// 一个枚举实例
    /// </summary>
    public static class EnumHelper
    {
        public enum EnumExample
        {
            [Description("号球")]
            CODE = 0,
            [Description("数字")]
            DIGITAL,
            [Description("红球")]
            RED_BALL,
            [Description("蓝球")]
            BLUE_BALL,
            [Description("前区")]
            FIRST_BALL,
            [Description("后区")]
            SECOND_BALL,
        }

        /// <summary>
        /// 按枚举变量提取枚举的描述(标题)
        /// </summary>
        /// <param name="cs">枚举值,比如:EnumExample.CODE</param>
        /// <returns></returns>
        public static string GetDescription(EnumExample cs)
        {
            return GetEnumDescription(cs);
        }

        /// <summary>
        /// 按序号提取枚举的描述(标题)
        /// </summary>
        /// <param name="index">0开始的序号</param>
        /// <returns></returns>
        public static string GetDescription(int index)
        {
            Array array = Enum.GetValues(typeof(EnumExample));
            if (index < 0 || index >= array.Length) return "";
            EnumExample cs = (EnumExample)array.GetValue(index);
            return GetDescription(cs);
        }

        /// <summary>
        /// 按枚举名字提取的描述(标题)
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string GetDescription(string name)
        {
            string[] array = Enum.GetNames(typeof(EnumExample));
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i].ToUpper() == name.ToUpper())
                {
                    return GetDescription(index: i);
                }
            }
            return "";
        }

        /// <summary>
        /// 提取标题的基础函数
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
        }

        /// <summary>
        /// 将枚举转为三元组列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<Tuple<int, string, string>> ToList<T>()
        {
            List<Tuple<int, string, string>> r = new List<Tuple<int, string, string>>();
            Array xa = Enum.GetValues(typeof(T));
            string[] na = Enum.GetNames(typeof(T));
            for (int i = 0; i < na.Length; i++)
            {
                EnumExample cs = (EnumExample)xa.GetValue(i);
                r.Add(new Tuple<int, string, string>((int)cs, na[i], GetDescription(i)));
            }
            return r;
        }

        /// <summary>
        /// 另外一种按序号提取枚举描述的方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="index"></param>
        /// <returns></returns>
        public static string GetDescription<T>(int index)
        {
            List<Tuple<int, string, string>> r = ToList<T>();
            return r[index].Item3;
        }

        /// <summary>
        /// 应用实例
        /// </summary>
        /// <returns></returns>
        public static string Drive()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("1 按枚举变量提取描述");
            sb.AppendLine("EnumExample.CODE -> " + GetDescription(EnumExample.CODE));
            sb.AppendLine("2 按序号量提取描述");
            sb.AppendLine("EnumExample[3] -> " + GetDescription(3));
            sb.AppendLine("3 按枚举名提取描述(大小写无关)");
            sb.AppendLine("EnumExample[\"code\"] -> " + GetDescription("code"));
            sb.AppendLine("4 转换为三元组");
            int idx = 0;
            foreach (Tuple<int, string, string> tx in ToList<EnumExample>())
            {
                sb.Append(idx + ": ");
                sb.Append("value=" + tx.Item1.ToString() + " ");
                sb.Append("name=" + tx.Item2.ToString() + " ");
                sb.AppendLine("description=" + tx.Item3.ToString() + " ");
                idx++;
            }
            sb.AppendLine("5 按三元组的序号提取描述");
            sb.AppendLine("Tuple[3] -> " + GetDescription<EnumExample>(3));
            return sb.ToString();
        }
    }
}

运行结果:

可以把 枚举enum 当作 类class 来使用就方便多了。

3 未来

.NET 8 之后。

国家把大量的资金投入高校与研究所,等于肉包子打狗,

别指望他们能写出任何一个有用的软件。

如果你的枚举类型只是用来表示一些简单的常量,而且不需要进行复杂的操作或逻辑,那么你可以使用枚举,它更简单,更直观,更高效。但是,如果你的枚举类型需要包含一些额外的信息,或者需要提供一些特定的方法,或者需要实现一些接口,或者需要继承一些类,那么你可以使用枚举类 Enumeration ,它更灵活,更易于维护。

Enumeration类是一个抽象类,它实现了IComparable接口,有两个属性:Name和Id,分别表示枚举的名称和值。它的构造函数接受两个参数,用于初始化这两个属性。它重写了ToString方法,返回Name属性的值。它还重写了Equals和GetHashCode方法,用于判断两个枚举对象是否相等,以及计算枚举对象的哈希值。它还提供了以下几个静态方法:

GetAll<T>:返回一个包含所有枚举对象的数组,其中T是Enumeration的子类。
AbsoluteDifference(Enumeration firstValue, Enumeration secondValue):返回两个枚举对象的Id属性的绝对差值。
FromValue<T>(int value):根据value参数查找对应的枚举对象,如果不存在则抛出异常。
FromDisplayName<T>(string displayName):根据displayName参数查找对应的枚举对象,如果不存在则抛出异常。
Parse<T, K>(K value, string deion, Func<T, bool> predicate):根据value参数和predicate委托查找对应的枚举对象,如果不存在则抛出异常。这是一个私有方法,被FromValue<T>和FromDisplayName<T>方法调用。

Enumeration类的设计非常精巧,它提供了一种通用的方式来创建枚举类型,只需要继承它并定义一些静态字段即可。那么,这样的设计到底有哪些好处呢?其实,通过与枚举进行对比,就可以找到答案,我们来看一看它们的区别:枚举类可以包含更多的信息,而不仅仅是一个整数值。例如,OrderStatus类除了有Id属性外,还有Name属性,用于表示订单状态的名称。这样可以方便地在界面上显示订单状态,而不需要额外的转换逻辑。而枚举只能表示一个整数值,如果要显示名称,就需要使用switch语句或者字典来映射。
枚举类可以提供更多的方法,而不仅仅是一些基本的操作。例如,OrderStatus类提供了List,FromName,From等方法,用于获取所有的订单状态,或者根据名称或值查找订单状态。而枚举只能使用Enum类的一些静态方法,如Enum.GetValues,Enum.GetName,Enum.Parse等,这些方法的参数和返回值都是object类型,需要进行类型转换,而且容易出错。
枚举类可以实现接口,而枚举不能。例如,Enumeration类实现了IComparable接口,表示它可以进行比较。这样可以方便地对枚举对象进行排序,或者使用一些LINQ方法,如Min,Max,OrderBy等。而枚举不能实现接口,只能使用默认的比较规则,即按照整数值的大小比较。
枚举类可以继承其他类,而枚举不能。例如,OrderStatus类继承了Enumeration类,这样可以方便地复用Enumeration类的一些通用的方法和属性,而不需要重复编写代码。而枚举不能继承其他类,只能继承System.Enum类,这是一个密封的类,不能被修改或扩展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/327263.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

01章【JAVA开发入门】

计算机基本概念 计算机组成原理 计算机组装 计算机&#xff1a;电子计算机&#xff0c;俗称电脑。是一种能够按照程序运行&#xff0c;自动、高速处理海量数据的现代化智能电子设备。由硬件和软件所组成&#xff0c;没有安装任何软件的计算机称为裸机。常见的形式有台式计算机、…

Apache POI 导出Excel报表

大家好我是苏麟 , 今天聊聊Apache POI . Apache POI 介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下&#xff0c;POI 都是用于操作 E…

slint 1.3.2 官方文档翻译04

主要使用 有道翻译。希望能够对 初学者 有所帮助 翻译自&#xff1a;Builtin Enumerations - Slint 1.3.2 Reference Builtin Enumerations 内置的枚举 AccessibleRole 可访问角色 This enum represents the different values for the accessible-role property, used to d…

Vue3-TS中的接口-泛型-自定义类型

1首先一般在src下新建types文件夹&#xff0c;用来存放接口类型 2定义一个接口&#xff0c;用于限制person对象的具体属性 当需要用这个类型形成数组时&#xff0c;有2种写法 export type Persons Array<PersonInter> export type Persons PersonInter[] 3在文件中使…

八:分布式锁

1、为什么要使用分布式锁 锁是多线程代码中的概念&#xff0c;只有多任务访问同一个互斥的共享资源时才需要锁。单机应用开发时一般使用synchronized或lock。多线程的运行都是在同一个JVM之下。应用是分布式集群&#xff0c;属于多JVM的工作环境&#xff0c;JVM之间已经无法通过…

数据结构--排序

参考【算法】排序算法之希尔排序 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/122632213 1. 排序的定义 2. 插入排序 2.1 直接插入排序 在插入第i&#xff08;i>1)个记录时&#xff0c;前面的i-1个记录已经排好序 void insertSort(int r[],int n) {for(int i2;i<…

JMeter定时器之同步定时器

JMeter定时器之同步定时器 1. 背景2. 目的3. 介绍4. 例子4.1单个请求4.2多个请求 1. 背景 在实际生活中大家肯定遇到过一种场景&#xff0c;就是在某一时间或某一时刻&#xff0c;某件商品进行抢购&#xff0c;相当于秒杀&#xff1b;但是用JMeter进行测试的时候&#xff0c;如…

反向代理的本质是什么?

反向代理是一种网络架构模式&#xff0c;通常用于提供静态内容、处理安全、负载均衡和缓存等任务。在这种架构中&#xff0c;客户端发送的请求首先到达反向代理服务器&#xff0c;然后由反向代理服务器将请求转发给后端的实际服务器。反向代理服务器可以处理和修改请求和响应&a…

GPT应用开发:运行你的第一个聊天程序

本系列文章介绍基于OpenAI GPT API开发应用的方法&#xff0c;适合从零开始&#xff0c;也适合查缺补漏。 本文首先介绍基于聊天API编程的方法。 环境搭建 很多机器学习框架和类库都是使用Python编写的&#xff0c;OpenAI提供的很多例子也是Python编写的&#xff0c;所以为了…

Unity解决Udp客户端无法接收数据的问题

Unity解决Udp客户端无法接收数据的问题 在我之前做过的项目中&#xff0c;其中不少涉及Udp客户端的项目。在这些项目中&#xff0c;一般只需要实现客户端向服务器端发送数据的功能就可以了&#xff0c;一般都不用接收服务器端发送的数据&#xff0c;但是也有同学使用了我分享的…

Java研学-三层架构实现简单登录操作

一 登录流程 将服务器资源给有权限的人访问&#xff0c;只有登录的管理员可以访问员工信息进行 CRUD 二 三层架构 Web 开发中的最佳实践&#xff1a;分层开发模式将整个业务应用划分为&#xff1a;表现层、业务逻辑层、数据访问层。区分层次的目的即为了“高内聚低耦合”的思想…

UML-实现图(组件图和部署图)

实现图是从系统的层次来描述的&#xff0c;描述硬件的组成和布局&#xff0c;描述软件系统划分和功能实现。 UML-实现图&#xff08;组件图和部署图&#xff09; 一、组件图1.组件图的元素&#xff08;1&#xff09;组件&#xff08;2&#xff09;接口&#xff08;3&#xff09…

Python爬虫---scrapy框架---当当网管道封装

项目结构&#xff1a; dang.py文件&#xff1a;自己创建&#xff0c;实现爬虫核心功能的文件 import scrapy from scrapy_dangdang_20240113.items import ScrapyDangdang20240113Itemclass DangSpider(scrapy.Spider):name "dang" # 名字# 如果是多页下载的话, …

深度解析Dubbo的可扩展机制SPI源码:从理论到实践,打造高效、稳定的分布式服务框架

Dubbo SPI架构图 Demo // 获取Protocol的ExtensionLoader实例 ExtensionLoader<Protocol> extensionLoader ExtensionLoader.getExtensionLoader(Protocol.class);// 通过ExtensionLoader获取名为"dubbo"的Protocol扩展点实例 Protocol dubboProtocol exte…

线性代数——行列式按行(列)展开

目录 一、余子式&#xff1a;将行列式某元素所在行和列的元素全去掉 剩余部分所构成的行列式&#xff0c;称为该元素的余子式 二、代数余子式 三、行列式等于它的任一行&#xff08;列&#xff09;的各元素与对应代数余子式乘积之和 四、行列式某行元素&#xff08;列&…

【论文阅读】Latent Consistency Models (LDMs)、LCM-LoRa

文章目录 IntroductionPreliminariesDiffusion ModelsConsistency Models Latent Consistency ModelsConsistency Distillation in the Latent SpaceOne-Stage Guided Distillation by Solving Augmented PF-ODEAccelerating Distillation with Skipping Time StepsLatent Cons…

Leetcode22-旅行终点站(1436)

1、题目 给你一份旅游线路图&#xff0c;该线路图中的旅行线路用数组 paths 表示&#xff0c;其中 paths[i] [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站&#xff0c;即没有任何可以通往其他城市的线路的城市。 题目数据保证线路…

TCP 的三次握手和四次挥手

Java 面试题 TCP 三次握手 第一次握手&#xff1a;客户端向服务端发送SYN包。报文中标志位SYN1&#xff0c;序列号seqx&#xff08;x为随机整数&#xff09;。此时客户端进入了 SYN_SEND 同步已发送状态。 第二次握手&#xff1a;服务端回复客户端SYNACK包。报文中标志位SYN1&…

vivado IP使用

使用IP源 注意&#xff1a;有关IP的更多信息&#xff0c;包括添加、打包、模拟和升级IP&#xff0c;请参阅VivadoDesign Suite用户指南&#xff1a;使用IP&#xff08;UG896&#xff09;进行设计。在Vivado IDE中&#xff0c;您可以在RTL项目中添加和管理以下类型的IP核心&…

rust跟我学:文件时间属性获得方法

图为RUST吉祥物 大家好,我是get_local_info作者带剑书生,这里用一篇文章讲解get_local_info是怎样获得杀毒软件的病毒库时间的。 首先,先要了解get_local_info是什么? get_local_info是一个获取linux系统信息的rust三方库,并提供一些常用功能,目前版本0.2.4。详细介绍地址…