C# 类与结构的区别详解
在 C# 中,类(Class)和结构(Struct)是两种不同的数据类型,尽管它们都能封装数据和行为,但在设计目的和底层机制上有显著区别。
1. 类型分类
类是引用类型(Reference Type):
变量存储的是对象的引用(内存地址),多个变量可以指向同一个对象。
结构是值类型(Value Type):
变量直接存储数据的副本,赋值时会发生值的复制。
// 类(引用类型)
MyClass obj1 = new MyClass();
MyClass obj2 = obj1; // obj2 和 obj1 指向同一对象
// 结构(值类型)
MyStruct s1 = new MyStruct();
MyStruct s2 = s1; // s2 是 s1 的独立副本2. 内存分配
类实例分配在堆(Heap)上,由垃圾回收器(GC)管理。
结构实例通常分配在栈(Stack)上(除非被装箱或作为类的成员),生命周期由作用域决定,效率更高。
3. 继承与多态
类支持继承和多态,可以继承自另一个类,并实现多个接口。
结构不能继承其他结构或类,只能实现接口(隐式继承 System.ValueType)。
class Animal { } // 类可以继承
class Dog : Animal { } // 合法
struct Point { } // 结构不能继承
// struct Point3D : Point { } // 非法!4. 默认构造函数
类可以有显式无参构造函数,如果没有定义,编译器会生成一个默认构造函数。
结构不能定义无参构造函数,编译器自动生成一个默认构造函数,将所有字段初始化为默认值(如数值为0)
struct MyStruct
{
public int X;
// public MyStruct() { } // 非法!结构不能自定义无参构造函数
}5. 初始化与 new
类必须通过 new 实例化(否则为 null)。
结构可以不使用 new,直接声明变量(但需显式初始化所有字段)。
MyClass obj; // 未初始化,默认 null
// obj.Method(); // 运行时错误(NullReferenceException)
MyStruct s; // 已分配内存,但字段未初始化
// s.X = 10; // 必须先初始化字段才能使用6. 性能考量
结构适合轻量级对象(如坐标 Point、颜色 Color),避免堆分配和 GC 开销。
类适合需要复杂逻辑、生命周期较长或较大的对象。
7. 适用场景
使用类:
需要继承或多态。
需要引用语义(共享数据)。
对象较大或频繁修改(避免值复制开销)。
使用结构:
小规模、不可变(Immutable)的数据(如 DateTime)。
需要值语义(独立副本)。
避免堆分配(高频创建的场景)