在 C# 中,类(class)结构体(struct) 都可以用来定义自定义类型,封装数据和行为,但它们在底层机制和使用场景上有本质区别。作为初级 C# 工程师,理解这些区别非常重要。


✅ 核心区别总结

特性 类(class 结构体(struct
类型类别 引用类型(Reference Type) 值类型(Value Type)
内存分配 分配在 堆(Heap) 通常分配在 栈(Stack) 上(或内联)
赋值行为 复制引用(两个变量指向同一对象) 复制整个值(两个独立副本)
默认构造 可以有无参/有参构造函数 总是有一个隐式的无参构造函数(不能删除)
继承 支持继承(单继承) 不能继承其他 struct 或 class(但可实现接口)
null 可以为 null 不能为 null(除非用 Nullable<T>,如 int?
性能 涉及堆分配和垃圾回收(GC) 无 GC 开销,适合高频小对象
适用场景 大型、复杂、有生命周期的对象 小型、简单、频繁创建的数据(如坐标、颜色)

🔍 详细解释 + 示例

1. 引用类型 vs 值类型(最关键!)

类(引用类型):
class PointClass
{
    public int X, Y;
    public PointClass(int x, int y) { X = x; Y = y; }
}

var p1 = new PointClass(1, 2);
var p2 = p1;        // p2 和 p1 指向同一个对象
p2.X = 10;
Console.WriteLine(p1.X); // 输出 10!因为 p1 和 p2 是同一个对象
结构体(值类型):
struct PointStruct
{
    public int X, Y;
    public PointStruct(int x, int y) { X = x; Y = y; }
}

var p1 = new PointStruct(1, 2);
var p2 = p1;        // p2 是 p1 的完整副本
p2.X = 10;
Console.WriteLine(p1.X); // 输出 1!p1 不受影响

💡 关键记忆点

  • 类 → 共享数据(改一个,另一个也变)
  • 结构体 → 独立副本(改一个,另一个不变)

2. 能否为 null?

PointClass c = null;      // ✅ 合法
PointStruct s = null;     // ❌ 编译错误!

// 但可以用可空类型:
PointStruct? s2 = null;   // ✅ 合法(相当于 Nullable<PointStruct>)

3. 继承与多态

  • :支持继承、虚方法、多态。

    class Animal { public virtual void Speak() => Console.WriteLine("..."); }
    class Dog : Animal { public override void Speak() => Console.WriteLine("Woof!"); }
    
  • 结构体不能继承其他 struct 或 class,但可以实现接口。

    struct Point : IEquatable<Point>
    {
        public bool Equals(Point other) => X == other.X && Y == other.Y;
    }
    

⚠️ 所有 struct 都隐式继承自 System.ValueType,而 ValueType 继承自 object,但这对开发者透明。


4. 构造函数限制

  • 结构体不能有显式的无参构造函数(C# 10 之前),且字段不能在声明时初始化(除非是 const 或 static)。

    struct BadStruct
    {
        public int X = 10; // ❌ C# 9 及之前不允许(C# 10+ 允许)
        public BadStruct() { } // ❌ 不能显式定义无参构造(C# 10+ 允许但有限制)
    }
    
  • 没有这些限制。

💡 C# 10+ 放宽了 struct 的限制,但作为初学者,建议仍按传统方式使用。


5. 性能与使用建议

使用 struct 当…… 使用 class 当……
数据小(≤ 16 字节,如 Point, Color 数据大或复杂
生命周期短、频繁创建(如循环中) 需要继承或多态
行为像“值”(如 int, DateTime 行为像“对象”(如 Person, Order
不需要 null 语义 需要 null 表示“无”

📌 .NET 官方建议:

“如果类型满足以下所有条件,考虑使用 struct:

  • 逻辑上表示单个值(如 int
  • 实例大小小于 16 字节
  • 不可变(immutable)
  • 不需要频繁装箱”

✅ 常见内置例子

类型 是 class 还是 struct?
string class
int, bool, double struct
DateTime, Guid, TimeSpan struct
List<T>, StringBuilder class
Point (System.Drawing) struct

💡 初学者一句话总结:

class 表示“对象”,用 struct 表示“值”。
不确定时,优先用 class;只有当你明确需要“值语义”且数据很小时,才用 struct

问题

结构体的基本类型是什么?

是System.ValueType

是否从结构体继承?

不,所有结构体都是密封的,因为所有值类型都是密封的。

做二维坐标系中,你会怎么表示一个点?

创建一个具有两个float只读属性x和y的结构体。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐