C#结构体(Struct)详解

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


‌结构体核心特点‌

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

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

‌结构体 vs 类‌

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

‌结构体定义示例‌

csharp 复制代码
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})");
}

‌使用结构体‌

csharp 复制代码
// 创建结构体实例
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 或接口类型时)。

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

相关推荐
m0_371356151 小时前
【测试框架篇】单元测试框架pytest(5):setup和teardown的详细使用
开发语言·python·单元测试·pytest
锋君1 小时前
C# JObject 快速定位节点值
开发语言·c#
半熟的皮皮虾2 小时前
从头开始开发基于虹软SDK的人脸识别考勤系统(python+RTSP开源)(五)补充剩余内容
开发语言·python
站在墙头上3 小时前
java虚拟机(JVM)以及各种参数详解
java·开发语言·jvm
Long_poem3 小时前
【自学笔记】R语言基础知识点总览-持续更新
开发语言·笔记·r语言
luckyext3 小时前
串口通信ASCII码转16进制及C#串口编程完整源码下载
开发语言·后端·stm32·单片机·mcu·物联网·c#
zhu_superman4 小时前
c语言中的未定义行为
c语言·开发语言
小爬虫程序猿4 小时前
衣联网的商品列表页面结构是怎样的?
开发语言·爬虫·python
孔令飞4 小时前
18 | 实现简洁架构的 Handler 层
开发语言·ai·云原生·golang·kubernetes
成风6934 小时前
c++比较与对比动态内存分配和回收运算符new,new[],delete,delete[]。
开发语言·c++