csharp:变量:结构体

C# 结构体 (Struct) 详解

在 C# 中,结构体 (Struct) 是一种轻量级的数据类型。与类(Class)不同,结构体是值类型 (Value Type),这使得它在特定的性能敏感场景下具有极大的优势。

结构体使用 ``struct`` 关键字定义。它通常用于封装包含少量相关变量的数据组,例如坐标点、颜色值或复数。

public struct Point
{
    public int X { get; }
    public int Y { get; }
 
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
 
    public override string ToString() => $"({X}, {Y})";
}

这是 C# 面试和架构设计中最常见的问题。核心区别在于内存分配赋值行为

特性 结构体 (Struct) 类 (Class)
类型种类 值类型 (Value Type) 引用类型 (Reference Type)
存储位置 通常在栈 (Stack) 上(或内联在其他对象中) 总是分配在托管堆 (Heap)
赋值行为 复制值。赋值给新变量时,会拷贝整个数据副本。 复制引用。赋值给新变量时,两个变量指向同一个对象。
垃圾回收 (GC) 不涉及 GC(随作用域自动释放),对 GC 压力极小。 需要 GC 回收,频繁创建销毁会造成 GC 压力。
继承 不支持继承(不能继承其他类或结构体),但可以实现接口 (Interface) 支持完整的继承体系 (Inheritance)。
默认值 不能为 null(除非使用 Nullable<T>,即 `int?`),默认值为所有字段归零。 默认为 null。
析构函数 不支持析构函数 (Finalizer)。 支持析构函数。

虽然它们都是值类型,但用途完全不同。

特性 结构体 (Struct) 枚举 (Enum)
本质 复合数据结构。可以包含字段、属性、方法、构造函数等。 命名常量的集合。底层通常只是一个整数 (int, byte 等)。
数据承载 用于存储多个相关联的数据(如 X 和 Y 坐标)。 用于表示单一的状态、选项或模式(如 Color.Red, Week.Monday)。
逻辑 可以包含业务逻辑(方法)。 不能包含方法(虽然可以使用扩展方法模拟)。
用途 描述一个“对象”或“实体”的轻量级表现。 描述一组有限的“选项”或“类别”。

示例对比:

  • Enum: `GameState { Playing, Paused, GameOver }` (只表示状态)
  • Struct: `PlayerState { int Health; Vector3 Position; }` (包含具体数据)

微软官方建议,只有当类型满足以下所有条件时,才考虑使用结构体:

  1. 逻辑上表示单一值:类似于基本类型(int, double),如坐标点、复数。
  2. 实例体积很小:通常建议实例大小小于 16 字节。如果大于这个大小,复制值的开销可能会超过引用传递的开销。
  3. 不可变 (Immutable):结构体创建后,其字段值最好不要改变。
  4. 不需要频繁装箱 (Boxing):如果需要频繁将该类型转换为 `object` 或接口,装箱操作会抵消结构体的性能优势。

在使用结构体时,强烈建议将其设计为不可变的。因为结构体是值拷贝,修改副本不会影响原始变量,这在可变结构体中极易导致难以排查的 Bug。

错误示范 (可变结构体):

struct MutablePoint { public int X; public int Y; }
// ...
MutablePoint p1 = new MutablePoint { X = 10 };
MutablePoint p2 = p1; // p2 是 p1 的副本
p2.X = 20; 
// 此时 p1.X 仍然是 10,这往往不符合直觉

正确示范 (不可变结构体):

readonly struct ImmutablePoint 
{
    public int X { get; }
    public int Y { get; }
    public ImmutablePoint(int x, int y) { X = x; Y = y; }
}
// 使用 readonly 关键字可以强制编译器检查不可变性
  • Struct: 为了性能(高频计算、海量小对象、减少 GC)。
  • Class: 为了面向对象特性(继承、多态、大型业务对象)。
  • Enum: 为了代码可读性和状态管理。
请输入您的评论. 可以使用维基语法:
 

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • csharp/变量/结构体.txt
  • 最后更改: 2025/12/22 11:22
  • 张叶安