选 struct 还是 class 取决于三点:是否需共享状态、是否频繁复制、是否需要继承或虚方法;struct 赋值为值拷贝(含引用字段浅拷贝),class 为引用拷贝;struct 必须显式初始化所有字段,无参构造受限;仅当满足纯数据载体、≤16 字节、极少修改时才优先选 struct。

选 class 还是 struct?核心就看三点:要不要共享状态、会不会频繁复制、需不需要继承或虚方法。其他都是衍生影响。
赋值和传参时行为完全不同
这是最常踩坑的地方——你以为改的是副本,结果改了别人的数据,或者反过来。
-
class赋值或传参时只拷贝引用地址,c2 = c1后c1和c2指向同一块堆内存 -
struct赋值或传参时默认拷贝整个值(浅拷贝),s2 = s1后修改s2.X不会影响s1.X - ⚠️ 注意:如果
struct里包含string或class字段,拷贝的只是那个引用,不是深层对象——这叫“值语义 + 引用字段”,容易误判为深拷贝
struct Point { public int X; public int Y; public string Tag; }
class Entity { public int Id; public string Name; }
var p1 = new Point { X = 1, Y = 2, Tag = "A" };
var p2 = p1;
p2.X = 99;
p2.Tag = "B"; // ✅ p1.Tag 仍是 "A" —— string 是不可变引用,赋新值不改变原引用
var e1 = new Entity { Id = 1, Name = "Alice" };
var e2 = e1;
e2.Name = "Bob"; // ✅ e1.Name 也变成 "Bob"
构造函数和初始化规则差异很大
struct 的构造函数不是“可选功能”,而是强制约束:你写的每个构造函数都必须显式初始化所有字段。
2013年07月06日 V1.60 升级包更新方式:admin文件夹改成你后台目录名,然后补丁包里的所有文件覆盖进去。1.[新增]后台引导页加入非IE浏览器提示,后台部分功能在非IE浏览器下可能没法使用2.[改进]淘客商品管理 首页 列表页 内容页 的下拉项加入颜色来区别不同项3.[改进]后台新增/修改淘客商品,增加淘宝字样的图标和天猫字样图标改成天猫logo图标4.[改进]为统一名称,“分类”改
-
class可以只写带参构造,也能用无参new MyClass()(编译器自动补默认构造) -
struct不能定义无参构造函数(C# 10+ 允许但仅限于init成员场景,日常仍应避免) -
struct总有隐式无参构造:直接声明Point p;就能用,p.X自动是0 - ❌ 下面代码会编译失败:
struct BadPoint { public int X; public BadPoint(int y) { /* 忘了赋 X */ } }
什么时候该用 struct?别凭感觉,看这 3 个硬指标
不是“小就用 struct”,而是满足全部三条才考虑:
- 逻辑上是“纯数据载体”,比如
Vector3、Color、DateOnly,不封装行为或状态机 - 大小稳定且 ≤ 16 字节(.NET 推荐阈值),避免栈溢出或复制开销过大
- 设计为不可变(
readonly struct)或极少修改——因为每次赋值都在复制,改得勤反而更慢 - ✅ 推荐场景:
Span内部字段、DTO 中的坐标/金额/时间戳结构体、数学库中的向量/矩阵 - ❌ 禁止场景:含
event、virtual方法、大数组字段、需要IDisposable的类型
最容易被忽略的一点:struct 在 class 字段里、数组里、async 状态机里,其实都分配在堆上——“struct 在栈上”只是局部变量的常见情况,不是铁律。性能优化前,先用 dotnet-counters 或 PerfView 看真实分配行为,别靠直觉猜。







