

新闻资讯
技术学院选 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 的构造函数不是“可选功能”,而是强制约束:你写的每个构造函数都必须显式初始化所有字段。
class 可以只写带参构造,也能用无参 new MyClass()(编译器自动补默认构造)struct 不能定义无参构造函数(C# 10+ 允许但仅限于 init 成员场景,日常仍应避免)struct 总有隐式无参构造:直接声明
Point p; 就能用,p.X 自动是 0
struct BadPoint { public int X; public BadPoint(int y) { /* 忘了赋 X */ } }不是“小就用 struct”,而是满足全部三条才考虑:
Vector3、Color、DateOnly,不封装行为或状态机readonly struct)或极少修改——因为每次赋值都在复制,改得勤反而更慢Span 内部字段、DTO 中的坐标/金额/时间戳结构体、数学库中的向量/矩阵event、virtual 方法、大数组字段、需要 IDisposable 的类型最容易被忽略的一点:struct 在 class 字段里、数组里、async 状态机里,其实都分配在堆上——“struct 在栈上”只是局部变量的常见情况,不是铁律。性能优化前,先用 dotnet-counters 或 PerfView 看真实分配行为,别靠直觉猜。