首页 > 编程语言 >在 C# 中实现枚举的最佳使用

在 C# 中实现枚举的最佳使用

时间:2024-06-02 16:00:05浏览次数:23  
标签:C# System value 最佳 枚举 Windows using public

一.介绍

在 C# 编程语言中,枚举(enumeration)的缩写,是一种独特的数据类型,由一组命名常量(称为枚举器)组成。枚举用于建立一系列相互关联的整数常量,通过为这些常量分配描述性名称来增强代码的可读性和可管理性。

二.C# 中的枚举具有许多优点

1.增强可读性和可维护性: 枚举允许使用描述性名称来表示整数常量,从而增强代码的可读性和清晰度。这反过来又提高了代码库的可维护性,因为开发人员可以轻松理解每个常量的用途。

2.确保类型安全: 枚举在编译期间提供类型安全,将值分配给该枚举类型的预定义常量集内的变量。此功能有助于防止因使用不正确的值而导致的错误。

3.编译器辅助: 枚举值经过编译器的类型检查,确保只使用有效的枚举常量。这有助于在开发过程的早期阶段识别错误。

4.Intellisense 支持:
Visual Studio 等集成开发环境 (IDE) 为枚举提供 Intellisense 支持,从而简化与枚举的交互。开发人员可以在编写代码时查看可用枚举值及其说明的列表。

5.促进代码重构: 可以修改枚举值,也可以添加新值,而不会影响代码的其他部分。枚举提供的这种灵活性有助于保持整个代码库的一致性。

6.与 Switch 语句的兼容性: 枚举非常适合与 switch 语句一起使用,从而可以创建更清晰、更结构化的代码来处理多种情况。

7.最小化错误风险: 通过使用枚举,由于枚举常量在编译期间经过验证,因此因拼写错误或错误值导致错误的可能性会降低。

三.枚举的特征

1.枚举由一组预先确定的常量组成。

2.通过使用枚举可以增强类型安全性。

3.枚举可以进行迭代。

四.枚举的各种实现例子

示例 1

// 定义一个名为WeekDays表示星期的枚举
public enum WeekDays
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

如果尚未为枚举成员分配任何值,则第一个成员会自动分配 0 值。随后,其他成员的值将增加 1。

示例 2

整数值也可以明确分配给枚举。

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

如果您拥有一组预先确定的相互关联的值,并且这些值不太可能频繁更改,那么枚举就非常有用。这些值的示例包括星期几、月份、状态代码等。通过提供编译时类型安全性并使用描述性名称(而不是任意数字或字符串),枚举可以大大提高代码的可读性。

示例 3

在枚举中,分配给其成员的数值可以属于任何整数数字数据类型,例如 byte、int、short、long、ushort 等。

public enum ByteEnum : byte
{
    Value1,
    Value2,
    Value3
}

在此场景中,ExampleEnum 是一个枚举,其中每个元素(Value1、Value2、Value3)都由一个字节值表示。第一个元素(Value1)将被分配一个值 0,第二个元素(Value2)将被分配一个值 1,依此类推。

当处理字节范围(0 到 255)内的有限范围值时,使用字节作为枚举的基本类型会非常有利。与使用 int 等较大的整数类型相比,这种方法可以节省内存,特别是在存在大量枚举变量或内存效率至关重要的情况下,例如在嵌入式系统或低级编程中。

** 注意:** 默认情况下,枚举成员为 int 类型。

示例 4

Switch 语句经常使用枚举来与特定值进行比较。

public enum ByteEnum : byte
{
    Value1,
    Value2,
    Value3
}

private void SetSwitchStatementForEnum(ByteEnum byteEnum)
{
    switch (byteEnum)
    {
        case ByteEnum.Value1:
            break;
        case ByteEnum.Value2:
            break;
        case ByteEnum.Value3:
            break;
        default:
            break;
    }
}

示例 5

使用 getNames() 方法遍历所有值。

public enum WeekDays
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

public void SetEnumNames()
{
    foreach (string s in Enum.GetNames(typeof(WeekDays)))
    {
        Console.WriteLine(s);
    }
}

// Output
// Sun
// Mon
// Tue
// Wed
// Thu
// Fri
// Sat

示例 6

使用 getValues() 方法遍历所有值。

public enum WeekDays
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

public void SetEnumNames()
{
    foreach (WeekDays day in Enum.GetValues(typeof(WeekDays)))
    {
        Console.WriteLine(day.ToString());
    }
}

//Output

//Sun
//Mon
//Tue
//Wed
//Thu
//Fri
//Sat

示例 7

要使用枚举类型表示选项组合,请将每个选项的枚举成员定义为位字段。这意味着这些枚举成员的关联值应该是 2 的幂。通过这样做,您可以使用按位逻辑运算符 | 或 & 分别组合选项或求选项组合的交集。要指示枚举类型声明位字段,请对其应用 Flags 属性。以下示例演示如何在枚举类型的定义中包含典型组合。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpTestingArticles
{
    /// <summary>
    /// 枚举类型表示一周中的天,支持按位操作
    /// </summary>
    [Flags]
    public enum Days
    {
        None = 0b_0000_0000,  // 0,表示没有选择任何天
        Monday = 0b_0000_0001,  // 1,表示星期一
        Tuesday = 0b_0000_0010,  // 2,表示星期二
        Wednesday = 0b_0000_0100,  // 4,表示星期三
        Thursday = 0b_0000_1000,  // 8,表示星期四
        Friday = 0b_0001_0000,  // 16,表示星期五
        Saturday = 0b_0010_0000,  // 32,表示星期六
        Sunday = 0b_0100_0000,  // 64,表示星期日
        Weekend = Saturday | Sunday  // 表示周末,包括星期六和星期日
    }

    /// <summary>
    /// 演示使用Flags枚举类型Days的例子
    /// </summary>
    public class FlagsEnumExample
    {
        /// <summary>
        /// 主方法,展示如何使用Days枚举进行按位操作
        /// </summary>
        public static void Main()
        {
            // 设定会议日为星期一、星期三和星期五
            Days meetingDays = Days.Monday | Days.Wednesday | Days.Friday;
            Console.WriteLine(meetingDays);
            // 输出:
            // Monday, Wednesday, Friday
            // 输出设置的会议日

            // 设定在家工作的日子为星期四和星期五
            Days workingFromHomeDays = Days.Thursday | Days.Friday;
            Console.WriteLine($"Join a meeting by phone on {meetingDays & workingFromHomeDays}");
            // 输出:
            // Join a meeting by phone on Friday
            // 输出可以通过电话加入会议的日在家工作日

            // 检查星期二是否有会议
            bool isMeetingOnTuesday = (meetingDays & Days.Tuesday) == Days.Tuesday;
            Console.WriteLine($"Is there a meeting on Tuesday: {isMeetingOnTuesday}");
            // 输出:
            // Is there a meeting on Tuesday: False
            // 输出星期二是否有会议

            // 将整数37转换为Days枚举,表示的天是按位操作的结果
            var a = (Days)37;
            Console.WriteLine(a);
            // 输出:
            // Monday, Wednesday, Saturday
            // 输出整数37对应的天
        }
    }
}

示例 8

枚举成员可以被赋予各种值。修改枚举成员的默认值将导致其他成员被自动按顺序赋予递增值。

public enum ItemsExample
{
    Electronics,    // 0
    Food,           // 1
    Automotive = 6, // 6
    Arts,           // 7
    BeautyCare,     // 8
    Fashion         // 9
}

示例 9

枚举的每个成员都可以被分配不同的值。

public enum ItemsExample
{
    Electronics = 1,
    Food = 5,
    Automotive = 6,
    Arts = 10,
    BeautyCare = 11,
    Fashion = 15,
    WomanFashion = 15
}

示例 10

在 C# 中,如果要将枚举值的名称转换为字符串列表,可以使用 Enum.GetNames 方法。通过使用此方法,您将收到一个由枚举值名称组成的字符串数组。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpTestingArticles
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            List<string> enumNames = GetEnumNamesValues<ExampleEnum>();

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

        public static List<string> GetEnumNamesValues<T>() where T : Enum
        {
            return new List<string>(Enum.GetNames(typeof(T)));
        }
    }

    public enum ExampleEnum
    {
        Value1,
        Value2,
        Value3
    }
}

GetEnumNames 函数需要一个泛型类型参数 T,表示枚举类型。它使用 Enum.GetNames(typeof(T)) 来获取包含枚举值名称的字符串数组。然后,利用 List 构造函数将此数组转换为字符串列表。最终,该函数提供枚举名称列表。可以使用任何枚举类型调用 GetEnumNames,从而生成显示枚举值名称的字符串列表。

示例 11

在 C# 中,可以使用属性为枚举值添加描述。从 C# 7.0 开始,可以使用 System.ComponentModel.DescriptionAttribute 来实现此目的。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpTestingArticles
{
    /// <summary>
    /// Interaction logic for DescriptionEnumExample.xaml
    /// </summary>
    public partial class DescriptionEnumExample : Window
    {
        public DescriptionEnumExample()
        {
            InitializeComponent();
            // Access the description of each enum value
            Console.WriteLine(GetDescription(DescriptionEnumClass.Value1)); // Output: first value
            Console.WriteLine(GetDescription(DescriptionEnumClass.Value2)); // Output: second value
            Console.WriteLine(GetDescription(DescriptionEnumClass.Value3)); // Output: third value
        }

        public static string GetDescription(Enum value)
        {
            var field = value.GetType().GetField(value.ToString());
            var attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
            return attribute == null ? value.ToString() : attribute.Description;
        }
    }

    public enum DescriptionEnumClass
    {
        [Description("first value")]
        Value1,
        [Description("second value")]
        Value2,
        [Description("third value")]
        Value3
    }
}

示例 12

用户可以为枚举元素生成个性化的显示值。

  using System.Reflection;
using System.Windows;

namespace WpTestingArticles
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // 获取每个枚举值的显示名称
            string name = EnumDisplayNameHelper.GetEnumDisplayName(eEmployeeInfo.Name); // 输出: Name of the employee
            string age = EnumDisplayNameHelper.GetEnumDisplayName(eEmployeeInfo.Age); // 输出: Age of the employee
        }
    }

    /// <summary>
    /// 自定义枚举显示名称属性
    /// </summary>
    public class CustomEnumDisplayNameAttribute : Attribute
    {
        private string _displayName;

        /// <summary>
        /// 枚举显示名称
        /// </summary>
        public string DisplayName
        {
            get { return _displayName; }
            set { _displayName = value; }
        }
    }

    /// <summary>
    /// 枚举显示名称助手类
    /// </summary>
    public static class EnumDisplayNameHelper
    {
        /// <summary>
        /// 获取枚举值的显示名称
        /// </summary>
        /// <param name="value">枚举值</param>
        /// <returns>显示名称</returns>
        public static string GetEnumDisplayName(this Enum value)
        {
            // 获取枚举字段信息
            FieldInfo field = value.GetType().GetField(value.ToString());

            // 获取自定义显示名称属性
            CustomEnumDisplayNameAttribute attribute = Attribute.GetCustomAttribute(field, typeof(CustomEnumDisplayNameAttribute)) as CustomEnumDisplayNameAttribute;

            // 返回显示名称或枚举值字符串
            return attribute == null ? value.ToString() : attribute.DisplayName;
        }
    }

    /// <summary>
    /// 员工信息枚举
    /// </summary>
    public enum eEmployeeInfo
    {
        // 使用自定义显示名称属性
        [CustomEnumDisplayNameAttribute(DisplayName = "Name of the employee")]
        Name,

        [CustomEnumDisplayNameAttribute(DisplayName = "Age of the employee")]
        Age,

        // 其他枚举值
    }
}

标签:C#,System,value,最佳,枚举,Windows,using,public
From: https://blog.csdn.net/xiefeng240601/article/details/139392564

相关文章

  • 【leetcode】——第 400 场周赛,2题选手签个到
    第一题:100307.候诊室中的最少椅子数给你一个字符串 s,模拟每秒钟的事件 i:如果 s[i]=='E',表示有一位顾客进入候诊室并占用一把椅子。如果 s[i]=='L',表示有一位顾客离开候诊室,从而释放一把椅子。返回保证每位进入候诊室的顾客都能有椅子坐的 最少 椅子数,假设候诊室......
  • Docker —— 从入门到实践 (yeasy)高清电子版pdf百度云
    书:pan.baidu.com/s/1-uwg0rd__HXJJvc9Gj7C8w?pwd=xrgo提取码:xrgoDocker概述:介绍Docker是什么,它的历史、特点以及为什么需要Docker。Docker安装与配置:指导读者如何在不同的操作系统上安装和配置Docker。Docker基础:讲解Docker的基本概念,如镜像、容器、Docker引擎等。Dockerfile......
  • C程序设计语言 (Brian W. Kernighan, Dennis M. Ritchie)电子版阅读笔记
    书:pan.baidu.com/s/1-uwg0rd__HXJJvc9Gj7C8w?pwd=xrgo提取码:xrgoC语言概述:介绍C语言的历史、特点以及在软件开发中的应用。数据类型:讲解C语言中的基本数据类型,如整型、浮点型、字符型等。变量与常量:介绍如何声明和使用变量、常量,以及它们的存储类别和生命周期。运算符与表达......
  • Keras深度学习框架实战(3):EfficientNet实现stanford dog分类
    1、通过EfficientNet进行微调以实现图像分类概述通过EfficientNet进行微调以实现图像分类,是一个使用EfficientNet作为预训练模型,并通过微调(fine-tuning)来适应特定图像分类任务的过程。一下是对相关重要术语的解释。EfficientNet:这是一个高效的卷积神经网络(CNN)架构,旨在通过......
  • 【JavaEE 进阶(二)】Spring MVC(下)
    ❣博主主页:33的博客❣▶️文章专栏分类:JavaEE◀️......
  • OpenPCDet模型导出ONNX
    前面介绍了采用OpenPCDet架构和自定义数据集训练了pointRCNN模型,也已经跑通了测试流程,但在实际应用过程中通常需要把模型导出成ONNX格式,然后借助其他框架用C++进行推理。这里记录一下pointRCNN导出流程以及常见的一些错误。其大体分为以下几步:弄清楚数据流确定网络架构改写网......
  • 深度学习论文翻译解析(二十二):Uniformed Students Student-Teacher Anomaly Detection W
    论文标题:UniformedStudentsStudent-TeacherAnomalyDetectionWithDiscriminativeLatentEmbbeddings论文作者: PaulBergmann MichaelFauser DavidSattlegger CarstenSteger论文地址:https://openaccess.thecvf.com/content_CVPR_2020/papers/Bergmann_Uninformed......
  • ca
    创建和管理一个CA及证书的生命周期任务详情1创建一个根CA,包括生成私钥和根证书。分析证书和0015,0034标准的符合情况2为一台服务器生成一个私钥和证书签署请求(CSR)。3使用根CA对服务器的CSR进行签名,生成服务器证书。4吊销该服务器的证书。1创建一个根CA,包括生成......
  • 【JUC】3-用户线程和守护线程
    一般情况下不做特别说明配置,默认都是用户线程 UserThread是系统的工作线程,它会完成这个程序需要完成的业务操作 DaemonThread是一种特殊的线程,为其它线程服务的,在后台默默的完成一些系统性的服务,比如垃圾回收线程就是最典型的例子守护线程作为一个服务线程,没有服务对象......
  • exgcd 通解(新)
    可能不全,老文章在这什么是通解,我们知道二元一次方程,是如果只有一个式子,那么解会有无数个,而通解就是指让我们只找到一个解就可以推出其他所有解的式子。注意以下变量都为整数。知道了定义下面就是推式子了,首先设\(x,y\)是\(ax+by=\gcd(a,b)\)的一个解,那么有\[y=\le......