详情

首页手游攻略 C#中的enum、struct和class三种类型的对比总结实用指南

C#中的enum、struct和class三种类型的对比总结实用指南

佚名 2026-09-08 15:30:02

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“C#中的enum、struct和class三种类型的对比总结”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

目录
  • 引言
  • 一、三者概览
  • 二、enum:常量的集合
    • 本质
    • 核心特点
    • 示例代码
    • 适用场景
  • 三、struct:轻量级数据容器
    • 本质
    • 核心特点
    • 示例代码
    • 赋值行为演示
    • 适用场景
  • 四、class:复杂业务对象
    • 本质
    • 核心特点
    • 示例代码
    • 适用场景
  • 五、关键差异详解
    • 1. 赋值行为对比
    • 2. 内存分配与性能
    • 3. 类型限制对比
  • 六、通用场景示例
    • 场景一:电商系统
    • 场景二:图形处理系统
    • 场景三:权限管理系统
  • 七、选择指南
    • 采用 enum 当
    • 采用 struct 当
    • 采用 class 当
  • 八、最佳实践总结
    • 1. enum 最佳实践
    • 2. struct 最佳实践
    • 3. class 最佳实践
  • 九、性能考量速查表
    • 结语

      引言

      在 C# 类型系统里,enumstructclass 是三种最基础且最重要的类型定义方式。它们分别服务于不同的场景,理解其本质区别和适用场景,对于编写高质量的代码至关重要。本文将系统性地总结这三种类型的特性、差异及采用建议。

      一、三者概览

      类型分类存储位置核心用途典型场景
      enum值类型定义一组命名常量状态、选项、类型标识
      struct值类型封装小型数据组坐标、参数、数据传输对象
      class引用类型定义复杂业务对象服务、管理器、实体模型

      二、enum:常量的集合

      本质

      enum 是值类型,本质上是整数类型(默认为 int)的封装,用来定义一组相关的命名常量。

      核心特点

      • 轻松纯粹:只能包含枚举成员,每个成员对应一个常量值
      • 类型安全:避免采用魔法数字,编译时检查
      • 兼容标志位:借助 [Flags] 特性兼容位运算组合

      示例代码

      // 基础枚举:订单状态
      public enum OrderStatus
      {
          Pending = 1, // 待支付
          Paid = 2, // 已支付
          Shipped = 3, // 已发货
          Delivered = 4, // 已送达
          Cancelled = 5 // 已取消
      }

      // 标志位枚举:用户权限
      [Flags]
      public enum Permission
      {
          None = 0,
          Read = 1 << 0, // 1
          Write = 1 << 1, // 2
          Delete = 1 << 2, // 4
          Admin = Read | Write | Delete // 7
      }

      // 使用示例
      public class Order
      {
          public OrderStatus Status { get; set; }
      }

      // 权限组合
      Permission userPerm = Permission.Read | Permission.Write;
      if (userPerm.HasFlag(Permission.Write))
      {
          Console.WriteLine("用户有写入权限");
      }

      适用场景

      • 状态机:订单状态、审批状态、任务状态
      • 选项设置:用户角色、权限级别、支付方式
      • 类型标识:日志级别、错误类型、文件类型
      • 方向/方位:方向(上/下/左/右)、星期几、月份

      三、struct:轻量级数据容器

      本质

      struct 是值类型,用来封装一组相关的数据字段,通常代表一个轻量级的、不可变的数据结构。

      核心特点

      • 值语义:赋值时复制整个数据,修改互不影响
      • 栈分配:小对象分配和释放效率高,无 GC 压力
      • 不可变性建议:微软建议将 struct 设计为不可变类型
      • 限制:不能继承类,不能定义无参构造函数(C# 10 前)

      示例代码

      // 推荐:不可变结构体
      public struct Color
      {
          public byte R { get; }
          public byte G { get; }
          public byte B { get; }
          
          public Color(byte r, byte g, byte b)
          {
              R = r;
              G = g;
              B = b;
          }
          
          public string ToHex() => $"#{R:X2}{G:X2}{B:X2}";
      }

      // 坐标结构体
      public struct Point
      {
          public double X { get; set; }
          public double Y { get; set; }
          
          public double DistanceTo(Point other)
          {
              double dx = X - other.X;
              double dy = Y - other.Y;
              return Math.Sqrt(dx * dx + dy * dy);
          }
      }

      // 数据传输对象
      public struct ProductInfo
      {
          public int Id;
          public string Name;
          public decimal Price;
      }

      赋值行为演示

      // struct:值类型,复制整个数据
      Point p1 = new Point { X = 10, Y = 20 };
      Point p2 = p1; // 复制 p1 的所有数据
      p2.X = 30; // 只修改 p2
      Console.WriteLine(p1.X); // 输出: 10 (p1 不受影响)

      // 对比 class
      class PointClass { public int X, Y; }
      PointClass c1 = new PointClass { X = 10, Y = 20 };
      PointClass c2 = c1; // c2 和 c1 指向同一个对象
      c2.X = 30; // 修改的是同一个对象
      Console.WriteLine(c1.X); // 输出: 30 (c1 也被修改)

      适用场景

      • 数学概念:坐标(Point)、尺寸(Size)、矩形(Rectangle)
      • 颜色值:RGB、ARGB 颜色表示
      • 日期区间:DateRange、TimeRange
      • 数值区间:Range、Interval
      • 轻量级 DTO:频繁传输的小型数据包

      四、class:复杂业务对象

      本质

      class 是引用类型,用来定义具有状态和行为的复杂对象,是面向对象编程的核心。

      核心特点

      • 引用语义:赋值时传递引用,多处共享同一实例
      • 堆分配:兼容复杂的生命周期管理
      • 完整的 OOP 兼容:继承、多态、封装、析构函数
      • 灵活性:可定义无参构造、析构函数、虚方法等

      示例代码

      // 抽象基类
      public abstract class User
      {
          public int Id { get; set; }
          public string UserName { get; set; }
          public abstract string GetRole();
          
          public virtual void Login()
          {
              Console.WriteLine($"{UserName} 登录成功");
          }
      }

      // 派生类
      public class Admin : User
      {
          public override string GetRole() => "管理员";
          
          public override void Login()
          {
              base.Login();
              Console.WriteLine("管理员权限已激活");
          }
      }

      public class RegularUser : User
      {
          public override string GetRole() => "普通用户";
      }

      // 服务类(单例模式)
      public class UserService
      {
          private static UserService _instance;
          private List<User> _users = new List<User>();
          
          private UserService() { }
          
          public static UserService Instance => _instance ??= new UserService();
          
          public void AddUser(User user) => _users.Add(user);
          public List<User> GetAllUsers() => _users;
      }

      // 实体类
      public class ShoppingCart
      {
          public int CartId { get; set; }
          private List<Product> _items = new List<Product>();
          
          public void AddItem(Product product)
          {
              _items.Add(product);
          }
          
          public decimal GetTotal()
          {
              return _items.Sum(item => item.Price);
          }
          
          ~ShoppingCart()
          {
              Console.WriteLine($"购物车 {CartId} 已销毁");
          }
      }

      适用场景

      • 业务实体:用户、订单、产品、客户
      • 服务类:用户服务、邮件服务、数据库服务
      • 管理器:连接池、缓存管理、设置管理
      • 复杂对象:需继承和多态的领域模型
      • UI 组件:窗体、控件、视图模型

      五、关键差异详解

      1. 赋值行为对比

      // enum:赋值整数常量
      OrderStatus status1 = OrderStatus.Paid;
      OrderStatus status2 = status1; // 复制值
      // struct:复制全部数据
      struct Rectangle { public int Width, Height; }
      Rectangle rect1 = new Rectangle { Width = 10, Height = 20 };
      Rectangle rect2 = rect1; // 复制整个结构体
      rect2.Width = 30; // rect1.Width 仍为 10
      // class:复制引用
      class RectangleClass { public int Width, Height; }
      RectangleClass rect3 = new RectangleClass { Width = 10, Height = 20 };
      RectangleClass rect4 = rect3; // 指向同一对象
      rect4.Width = 30; // rect3.Width 变为 30

      2. 内存分配与性能

      // struct:栈分配,GC 友好
      public void ProcessColors()
      {
          var colors = new Color[10000]; // 连续内存,访问快
          // 方法结束自动释放,无 GC 压力
      }

      // class:堆分配,GC 管理
      public void ProcessUsers()
      {
          var users = new List<User>(); // 堆分配,需 GC 回收
          users.Add(new Admin());
          users.Add(new RegularUser());
          // 需等待 GC 回收
      }

      3. 类型限制对比

      特性enumstructclass
      无参构造函数不兼容有限兼容完全兼容
      析构函数不兼容不兼容兼容
      继承类不兼容不兼容兼容
      实现接口兼容兼容兼容
      可为 null
      默认值第一个成员所有字段为默认值null

      六、通用场景示例

      综合运用三种类型的实际场景:

      场景一:电商系统

      // enum:订单状态
      public enum OrderStatus
      {
          Pending,
          Paid,
          Shipped,
          Completed,
          Cancelled
      }

      // enum:支付方式
      public enum PaymentMethod
      {
          CreditCard,
          Alipay,
          WeChat,
          BankTransfer
      }

      // struct:金额(不可变值类型)
      public struct Money
      {
          public decimal Amount { get; }
          public string Currency { get; }
          
          public Money(decimal amount, string currency)
          {
              Amount = amount;
              Currency = currency;
          }
          
          public Money Add(Money other)
          {
              if (Currency != other.Currency)
                  throw new InvalidOperationException("货币类型不一致");
              return new Money(Amount + other.Amount, Currency);
          }
      }

      // class:订单实体
      public class Order
      {
          public int OrderId { get; set; }
          public OrderStatus Status { get; set; }
          public PaymentMethod PaymentMethod { get; set; }
          public Money TotalAmount { get; set; }
          private List<OrderItem> _items = new List<OrderItem>();
          
          public void AddItem(Product product, int quantity)
          {
              _items.Add(new OrderItem(product, quantity));
              RecalculateTotal();
          }
          
          private void RecalculateTotal()
          {
              decimal total = _items.Sum(item => item.Subtotal.Amount);
              TotalAmount = new Money(total, "CNY");
          }
          
          public void Pay(PaymentMethod method)
          {
              PaymentMethod = method;
              Status = OrderStatus.Paid;
          }
      }

      场景二:图形处理系统

      // struct:颜色(值类型)
      public struct Color
      {
          public byte R, G, B, A;
          public Color(byte r, byte g, byte b, byte a = 255)
          {
              R = r; G = g; B = b; A = a;
          }
      }

      // struct:坐标点
      public struct Point
      {
          public int X, Y;
          public Point(int x, int y) { X = x; Y = y; }
      }

      // class:图形基类(引用类型)
      public abstract class Shape
      {
          public Color FillColor { get; set; }
          public abstract double GetArea();
          public abstract void Draw();
      }

      public class Rectangle : Shape
      {
          public Point Position { get; set; }
          public int Width { get; set; }
          public int Height { get; set; }
          
          public override double GetArea() => Width * Height;
          public override void Draw() { }
      }

      场景三:权限管理系统

      // enum:权限标志位
      [Flags]
      public enum Permission
      {
          None = 0,
          View = 1,
          Create = 2,
          Edit = 4,
          Delete = 8,
          Full = View | Create | Edit | Delete
      }

      // struct:权限组(轻量级组合)
      public struct PermissionGroup
      {
          public string Name { get; }
          public Permission Permissions { get; }
          
          public PermissionGroup(string name, Permission perms)
          {
              Name = name;
              Permissions = perms;
          }
          
          public bool HasPermission(Permission perm) => Permissions.HasFlag(perm);
      }

      // class:用户服务
      public class UserService
      {
          private Dictionary<string, PermissionGroup> _groups;
          
          public UserService()
          {
              _groups = new Dictionary<string, PermissionGroup>();
          }
          
          public void AddGroup(PermissionGroup group)
          {
              _groups[group.Name] = group;
          }
          
          public bool CheckPermission(string groupName, Permission required)
          {
              return _groups.TryGetValue(groupName, out var group) &&
                     group.HasPermission(required);
          }
      }

      七、选择指南

      采用 enum 当

      • 需定义一组相关的常量值(如状态、类型、选项)
      • 替代魔法数字,增强代码可读性
      • 需位标志组合(采用 [Flags]
      • 做 switch-case 判断

      采用 struct 当

      • 数据量小(建议 < 16 字节)
      • 代表单一的值(如坐标、颜色、范围)
      • 生命周期短暂,频繁新建销毁
      • 希望值语义,数据独立
      • 不需继承和多态

      采用 class 当

      • 对象包含复杂行为和状态
      • 需继承和多态
      • 对象较大,复制成本高
      • 需在多处共享同一实例
      • 需实现 IDisposable 进行资源管理

      八、最佳实践总结

      1. enum 最佳实践

      // ✅ 显式指定值,便于序列化
      public enum LogLevel
      {
          Debug = 10,
          Info = 20,
          Warning = 30,
          Error = 40
      }

      // ✅ 位标志使用 2 的幂
      [Flags]
      public enum FileAccess
      {
          None = 0,
          Read = 1,
          Write = 2,
          Execute = 4
      }

      // ❌ 避免复杂的逻辑判断
      // ❌ 不要在枚举中定义方法(使用扩展方法替代)

      2. struct 最佳实践

      // ✅ 设计为不可变类型
      public struct Point
      {
          public int X { get; }
          public int Y { get; }
          public Point(int x, int y) { X = x; Y = y; }
      }

      // ✅ 保持结构体小巧
      // ✅ 需要修改时传递 ref 参数
      public void UpdatePoint(ref Point point, int dx, int dy) { }

      // ❌ 避免在结构体中定义引用类型字段(会导致复制成本增加)
      // ❌ 避免频繁装箱拆箱

      3. class 最佳实践

      // ✅ 遵循 SOLID 原则
      // ✅ 需要继承时设计抽象基类
      public abstract class Repository<T> { }

      // ✅ 考虑使用接口定义契约
      public interface IUserService { }

      // ✅ 大型对象实现 IDisposable
      public class DatabaseConnection : IDisposable
      {
          public void Dispose() { /* 释放资源 */ }
      }

      九、性能考量速查表

      操作enumstructclass
      新建小对象(<16B)最快慢(堆分配)
      新建大对象N/A慢(复制成本高)快(引用传递)
      传递参数快(值复制)小对象快,大对象慢快(引用传递)
      GC 压力
      数组访问连续内存分散内存

      结语

      enumstructclass 是 C# 类型系统的三大基石,各有其独特的设计哲学和适用场景:

      • enum:用命名常量代替魔法数字,让代码更清晰
      • struct:用值语义封装轻量数据,让性能更高效
      • class:用引用语义构建复杂对象,让设计更灵活

      落到代码里,理解同时善用这三种类型,是写出高质量 C# 代码的关键。在真实项目中,根据数据大小、生命周期、共享需求和性能要求,选择最合适的类型,才能构建出既健壮又高效的应用程序。

      到此这篇关于C#中的enum、struct和class三种类型的对比总结的文章就介绍到这了,更多相关C# enum struct和class内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!

      您可能感兴趣的文章:

      • C#中struct, class的采用区别
      • C#基础教程之类class与结构struct的区别
      • C#中struct与class的区别详解
      • 区分C# 中的 Struct 和 Class
      • C#中struct和class的区别详解
      • C#中的枚举类型(Enum)介绍
      • C#枚举类型与位域枚举Enum

      相关资讯
      点击查看更多
      游戏推荐
      推荐专题
      热门阅读
      推荐下载