C#基础学习(一)复杂数据类型之枚举

一、复杂数据类型概述

1.1 为什么需要复杂类型?

当处理包含多个关联值的复合数据时,基础数据类型(int、string等)会面临以下问题:

  • 可读性差if(status == 2)中的数字难以理解
  • 维护困难:多个地方使用相同含义的魔法数字
  • 类型不安全:无法在编译时检查有效性

1.2 常见复杂类型

类型 特点 适用场景
类(Class) 引用类型,支持继承 业务实体建模
结构体(Struct) 值类型,轻量级 小型数据结构
枚举(Enum) 命名常量集合 状态/类型标识
数组(Array) 固定大小的集合 批量数据处理

那么是什么是枚举呢:

cs 复制代码
    //枚举是一个比较特别的存在
    //它是一个被命名的整形常量的集合
    //一般用它来表示 状态 类型等

    //申明枚举 和 申明枚举变量 是两个概念
    //申明枚举 :    相当于是 创建一个自定义的枚举类型
    //申明枚举变量 :使用申明的自定义枚举类型 创建一个枚举变量

二、枚举的核心价值

2.1 解决实际问题

优化前代码

cs 复制代码
if (order.Status == 3) // 3代表已发货
{
    // 处理发货逻辑
}

优化后代码

cs 复制代码
enum E_OrderStatus 
{
 Pending,//待定
 Processing,//加工
 Shipped //运输
}

if (order.Status == OrderStatus.Shipped)
{
    // 逻辑清晰可见
}

2.2 核心优势

  • 代码自文档化
  • 编译时类型检查
  • 避免无效值输入
  • 提升代码可维护性

三、枚举的声明与定义

3.1 基本语法

cs 复制代码
enum 枚举名称
{
    枚举项1,       // 默认从0开始
    枚举项2,       // 自动递增为1
    枚举项3 = 5,   // 显式赋值
    枚举项4        // 自动递增为6
}

3.2 声明位置规则

  1. 命名空间级别(推荐)​
cs 复制代码
namespace MyApplication
{
    enum Weekday { Mon, Tue, Wed }
}

2、​类/结构体内部

cs 复制代码
class Player
{
    enum State { Idle, Moving }
}

3、禁止在方法内部声明

cs 复制代码
void Process()
{
    // enum Error { } // 编译错误!
}

3.3 命名规范建议

  • 使用名词组合(ColorType优于ColorEnum)
  • 避免使用复数形式(Color代替Colors)
  • 首字母大写(符合Pascal命名法)
  • 最好在你的枚举类型前面加上E_,这样别人一下就能知道这是枚举类型的变量

四、枚举的基本使用

4.1 声明与赋值

cs 复制代码
    enum GameState 
    {
        MainMenu,
        Playing,
        Paused
    }

    class Game
    {
        GameState currentState = GameState.MainMenu;
    }

4.2 逻辑判断

cs 复制代码
// if判断
if (currentState == GameState.Playing)
{
    // 处理游戏逻辑
}

// switch判断(最佳实践)
switch (currentState)
{
    case GameState.MainMenu:
        ShowMenu();
        break;
    case GameState.Playing:
        UpdateGame();
        break;
    case GameState.Paused:
        ShowPauseMenu();
        break;
}

五、类型转换详解

cs 复制代码
    enum GameState 
    {
        MainMenu,
        Playing,
        Paused
    }

5.1 枚举与整型互转

cs 复制代码
// 枚举转int
GameState state = GameState.Playing;
int stateCode = (int)state; // 结果为1

// int转枚举(注意有效性检查)
int input = 2;
if (Enum.IsDefined(typeof(GameState), input))
{
    GameState newState = (GameState)input;
}

5.2 枚举与字符串互转

cs 复制代码
// 枚举转字符串
string stateName = GameState.Playing.ToString(); // "Playing"

// 字符串转枚举(严格区分大小写)
string input = "Paused";
if (Enum.TryParse(input, out GameState result))
{
    currentState = result;
}
else
{
    Console.WriteLine("无效状态!");
}
转换方向 代码示例 注意事项
枚举 → 整型 int code = (int)E_GameState.Playing; 直接显式转换
整型 → 枚举 E_GameState state = (E_GameState)2; 需验证值有效性
枚举 → 字符串 string str = E_GameState.Paused.ToString() 返回枚举项名称
字符串 → 枚举 Enum.Parse(typeof(E_GameState), "GameOver") 严格区分大小写,建议TryParse

六、枚举的高级用法

1、多状态组合(位标志)

在C#中,[Flags]是用于枚举的特殊特性(Attribute),它开启了枚举的位运算模式,让枚举值可以像开关位一样进行组合操作。后面我们在学习反射的时候会仔细讲述。

cs 复制代码
[Flags]
enum Permission
{
    None = 0,         // 0000
    Read = 1 << 0,    // 0001
    Write = 1 << 1,   // 0010
    Execute = 1 << 2, // 0100
    All = Read | Write | Execute // 0111
}

// 用户权限设置
var userPermission = Permission.Read | Permission.Write;

// 权限验证
if (userPermission.HasFlag(Permission.Write))
{
    Console.WriteLine("可执行写入操作");
}

参考使用:用户权限系统,文件属性设置。

2、配置选项管理

cs 复制代码
enum DisplayOptions
{
ShowHeader = 1    // 二进制 0001
ShowFooter = 2    // 二进制 0010 (1 << 1)
DarkMode = 4      // 二进制 0100 (1 << 2)
}

// 组合配置项
var currentOptions = DisplayOptions.ShowHeader | DisplayOptions.DarkMode;

// 配置检查
if ((currentOptions & DisplayOptions.DarkMode) != 0)
{
    ApplyDarkTheme();
}

这个示例确实基于位标志的原理,即使没有显式使用[Flags]特性,只要正确设置枚举值,仍然可以进行位运算操作。但是必须得保障每一个元素都是2的幂

3、游戏状态机

cs 复制代码
enum PlayerState
{
    Idle,
    Walking,
    Attacking,
    Dead
}

class Player
{
    private PlayerState _state;
    
    public void TakeDamage()
    {
        if (_state != PlayerState.Dead)
        {
            _state = PlayerState.Dead;
            PlayDeathAnimation();
        }
    }
}

4、API参数约束

cs 复制代码
enum SortOrder
{
    Ascending,
    Descending
}

// Web API 接口
[HttpGet("products")]
public IActionResult GetProducts(SortOrder order = SortOrder.Ascending)
{
    var query = order == SortOrder.Ascending 
        ? _db.Products.OrderBy(p => p.Price)
        : _db.Products.OrderByDescending(p => p.Price);
    
    return Ok(query.ToList());
}

5、UI控件状态管理

cs 复制代码
enum ButtonState
{
    Normal,
    Hover,
    Pressed,
    Disabled
}

void UpdateButtonAppearance(ButtonState state)
{
    switch (state)
    {
        case ButtonState.Hover:
            button.BackColor = Color.LightBlue;
            break;
        case ButtonState.Pressed:
            button.BackColor = Color.Blue;
            break;
        case ButtonState.Disabled:
            button.Enabled = false;
            break;
        default:
            button.ResetVisuals();
            break;
    }
}

总结:枚举类型主要是帮助我们分辨变量的含义。而非魔法数值,让人捉摸不透。OK,下一篇预告C#中的数组

相关推荐
陈天伟教授14 小时前
基于学习的人工智能(3)机器学习基本框架
人工智能·学习·机器学习·知识图谱
毕设源码-钟学长14 小时前
【开题答辩全过程】以 高校课程学习评价系统设计与实现为例,包含答辩的问题和答案
学习
lly20240614 小时前
HTML与CSS:构建网页的基石
开发语言
一只会写代码的猫14 小时前
面向高性能计算与网络服务的C++微内核架构设计与多线程优化实践探索与经验分享
java·开发语言·jvm
是小胡嘛15 小时前
C++之Any类的模拟实现
linux·开发语言·c++
fruge16 小时前
从第三方库中偷师:学习 Lodash 的函数封装技巧
学习
csbysj202016 小时前
Vue.js 混入:深入理解与最佳实践
开发语言
Gerardisite18 小时前
如何在微信个人号开发中有效管理API接口?
java·开发语言·python·微信·php
Want59518 小时前
C/C++跳动的爱心①
c语言·开发语言·c++
lingggggaaaa18 小时前
免杀对抗——C2远控篇&C&C++&DLL注入&过内存核晶&镂空新增&白加黑链&签名程序劫持
c语言·c++·学习·安全·网络安全·免杀对抗