C#结构体(Struct)详解

发布于:2025-03-13 ⋅ 阅读:(12) ⋅ 点赞:(0)

在 C# 中,‌结构体(struct)‌ 是一种值类型数据类型,适用于封装小型数据组。与类(class)不同,结构体在栈(Stack)上分配内存,且赋值时会发生值复制。以下是结构体的核心特性和用法:


‌结构体核心特点‌
结构提供了一种轻量级的数据类型,适用于表示简单的数据结构,具有较好的性能特性和值语义:

  • 值类型‌:赋值时复制整个数据,修改副本不影响原数据。
  • 结构可带有方法、字段、索引、属性、运算符方法和事件,适用于表示轻量级数据的情况,如坐标、范围、日期、时间等。
  • 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义无参构造函数。无参构造函数(默认)是自动- 定义的,且不能被改变(C# 10 前不能定义无参构造器,所有字段需在构造器中初始化。)。
  • 与类不同,结构不能继承其他的结构或类。
  • 结构不能作为其他结构或类的基础结构。
  • 结构可实现一个或多个接口。
  • 结构成员不能指定为 abstract、virtual 或 protected。
  • 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
  • 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
  • 结构变量通常分配在栈上,这使得它们的创建和销毁速度更快。但是,如果将结构用作类的字段,且这个类是引用类型,那么结构将存储在堆上。
  • 结构默认情况下是可变的,这意味着你可以修改它们的字段。但是,如果结构定义为只读,那么它的字段将是不可变的。

‌结构体 vs 类‌

特性 结构体(struct) 类(class)
类型 值类型(栈内存) 引用类型(堆内存)
继承 不支持 支持
默认构造器 C# 10 前无隐式无参构造器 有隐式无参构造器
赋值行为 复制值 复制引用
适用场景 小型、频繁创建的数据 复杂对象、需要继承的场景

‌结构体定义示例‌

public struct Point
{
    public int X;
    public int Y;

    // C# 10+ 允许显式无参构造器
    public Point()
    {
        X = 0;
        Y = 0;
    }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public void Print() => Console.WriteLine($"({X}, {Y})");
}

‌使用结构体‌

// 创建结构体实例
Point p1 = new Point(10, 20);
Point p2 = p1; // 值复制

p2.X = 30;     // 修改副本不影响原数据
p1.Print();     // 输出: (10, 20)
p2.Print();     // 输出: (30, 20)

// 使用无参构造器(C# 10+)
Point p3 = new Point();
p3.Print();     // 输出: (0, 0)

‌何时使用结构体?‌

  1. 数据量小‌:字段较少(通常少于 16 字节)。
  2. 不可变需求‌:设计为不可变类型(所有字段只读)。
  3. ‌避免装箱‌:减少值类型与引用类型转换的性能损耗。
  4. ‌高频实例化‌:如游戏中的坐标计算,减少堆内存压力。

‌注意事项‌

  • 避免大型结构体‌:复制成本高,可能降低性能。
  • ‌慎用可变结构体‌:修改副本可能导致预期外的行为。
  • ‌构造器必须初始化所有字段‌:否则编译报错。
  • ‌实现接口需谨慎‌:可能导致装箱操作(将结构体转为 object 或接口类型时)。

通过合理使用结构体,可以优化内存分配和程序性能,但需根据场景权衡值与引用类型的优缺点。


网站公告

今日签到

点亮在社区的每一天
去签到