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#中的数组

相关推荐
徐小黑ACG2 分钟前
GO语言 单元测试
开发语言·后端·golang·单元测试
码观天工6 分钟前
AI与.NET技术实操系列(九):总结篇 ── 探讨.NET 开发 AI 生态:工具、库与未来趋势
ai·c#·.net·ml.net
雨墨C10 分钟前
LLM-01-第一章-预训练/神经网络的激活函数(一)概述
人工智能·学习·自然语言处理·chatgpt·大模型·transformer
郭涤生21 分钟前
第二十一章:模板与继承_《C++ Templates》notes
开发语言·c++·笔记
郭涤生23 分钟前
第二十章:类型属性的重载_《C++ Templates》notes
开发语言·c++·笔记
mrbone1126 分钟前
Qt-Q_ENUM宏和QMetaEnum类
开发语言·qt·枚举·元对象系统·q_enum·qmetaenum
Water_Sounds36 分钟前
【FPGA开发】Cordic原理推导、Xilinx PG105手册解读
java·开发语言·fpga开发
2402_8813193043 分钟前
3.23学习总结
学习
胖大和尚1 小时前
Lua 的 Neovim 常用配置
开发语言·lua
流影ng1 小时前
Java中常见字符串操作
java·开发语言