C# 结构体 struct 完整精讲|值类型核心特性,对比类 class(新手易懂版)
前言
很多初学者分不清 struct 结构体 和 class 类。两者写法看起来十分相似,但底层内存分配、赋值拷贝逻辑天差地别。结构体属于自定义值类型,在设备参数存储、轻量数据打包场景高频使用。本文从内存原理、代码实操、核心坑点完整讲解。
一、前置基础:栈内存 vs 堆内存
先理清两种内存区别,才能彻底看懂结构体底层行为:
栈内存(Stack)
空间较小,读写速度快;用于存放值类型数据:int、double、bool、struct 结构体。方法执行完毕后自动释放内存,无需手动回收。
堆内存(Heap)
空间充足,存放引用类型:class类、数组、字符串。存储实体数据,依靠内存地址引用访问,由垃圾回收机制管理。
核心定义
struct 结构体:自定义值类型。作用是把多个不同类型的零散数据打包整合为一个整体。
外观语法和 class 高度相似,但是内存存储、拷贝机制完全不同,这是结构体与类最核心分界线。
二、结构体声明代码逐行解析
语法示例
csharp
运行
// 定义位置:Program类内部、Main方法外部,禁止写在Main方法里面
struct Book
{
public string name; //书名
public double price; //价格
public string desc; //书籍简介
public int count; //售卖数量
}
逐条解读
struct Book
struct:结构体关键字;Book 结构体名称,遵循大驼峰命名规范,代表我们自定义的数据模板。
public 类型 变量名;
结构体内部变量称为字段;public 公开修饰符,允许外部直接读写字段。
结构体最大优势:一个容器可以存放多种不同数据类型。
⚠️ 硬性语法规则
结构体不能定义在 Main() 方法内部,只能写在类内、方法外,和枚举 enum 定义规则一致。放在方法内直接编译报错!
没有结构体时代的痛点
如果不使用结构体,想要保存一本书的信息,需要单独定义一堆分散变量:
csharp
运行
string bookName = "西游记";
double bookPrice = 9.9;
string bookDesc = "猴子打妖怪";
int bookCount = 100;
数据零散,关联性差,代码难以维护。
使用结构体后,一本书的全部信息统一封装到 Book 模板中,逻辑清晰。工业上位机开发中,经常使用结构体存储各类设备参数。
三、结构体实例化、赋值拷贝实战(重点!区分 class 核心)
完整演示代码
csharp
运行
// 1.实例化结构体,对象初始化器批量赋值
Book book1 = new Book() { name = "西游记", price = 9.9, count = 100, desc = "猴子打妖怪" };
// 2.结构体赋值拷贝(重点)
Book book2 = book1;
// 3.修改book1内部所有字段
book1.name = "水浒传";
book1.price = 99.9;
book1.count = 200;
book1.desc = "梁山好汉";
// 4.打印输出
Console.WriteLine($"book1:{book1.name},售价{book1.price},销量{book1.count},简介:{book1.desc}");
Console.WriteLine($"book2:{book2.name},售价{book2.price},销量{book2.count},简介:{book2.desc}");
分步拆解底层逻辑
创建结构体实例 Book book1 = new Book()
结构体是值类型,执行代码时,直接在栈内存开辟一块独立空间;字段真实数据直接保存在栈中,不存在地址引用。
拷贝代码 Book book2 = book1;【重中之重】
结构体属于值类型,赋值时会执行完整数据深拷贝:
① 读取 book1 栈内存里全部字段数据;
② 在栈中新开辟一块独立内存;
③ 将所有数据完整复制,生成全新对象 book2;
✅ 内存中存在两份完全独立的数据,两者互不绑定!
修改 book1 的字段
仅仅修改 book1 对应栈空间的数据,完全不会影响 book2。
运行结果
plaintext
book1:水浒传,售价99.9,销量200,简介:梁山好汉
book2:西游记,售价9.9,销量9.9,简介:猴子打妖怪
关键结论:结构体拷贝之后,修改原对象,副本数据不会发生任何变化。
四、核心知识点总结(可直接背诵)
struct 结构体 = 自定义值类型,分配在栈内存;class 类是引用类型,分配在堆内存。
变量2 = 变量1 结构体赋值:完整复制一份全新数据,两者相互独立。
结构体不能写在方法内部,只能定义在类内、方法外部。
适合场景:轻量小型数据包(坐标、参数、配置信息),不适合存放大量复杂数据。
极易踩坑对比预告:
如果换成 class 类执行 Book book2 = book1,仅仅是复制地址,两个变量指向同一份数据;修改其中一个,另一个同步变化。

浙公网安备 33010602011771号