在 C# 里,很多初学者会把 struct 当成“写法像类、功能缩小版的类”,但真正需要先理解的是:它是值类型,这会直接影响赋值、传参和修改后的结果。下面按“怎么定义、怎么用、和类到底差在哪”三个问题展开,帮助你判断什么场景适合用结构,什么场景更该保留为类。
C# 结构是什么
struct 是 C# 中的值类型,用来表示一组轻量、紧凑的数据。常见例子包括坐标、日期、颜色、尺寸这类本身就更接近“数值组合”的对象。
它和 class 的最大区别不在语法,而在语义:类是引用类型,结构是值类型。也正因为如此,结构在赋值和传递时,行为更接近 int、float 这类内置类型。
原文提到“结构在栈上分配,类在堆上分配”,这是一种便于入门的理解方式。对日常使用来说,更重要的结论是:结构通常按值复制,类通常按引用访问。真正写代码时,先抓住这一点最有帮助。
如何定义一个结构
定义结构时,语法和定义类很接近,只是把 class 换成 struct。结构里同样可以放字段、构造函数和实例方法。

// www.ja vascriptcn.com code example
public struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
public void MoveTo(int newX, int newY)
{
X = newX;
Y = newY;
}
}
这个 Point 结构表示二维坐标点,包含两个字段 X 和 Y,以及一个带参数构造函数和一个 MoveTo 方法。对于这类“只描述少量数据,并附带少量行为”的模型,结构通常比类更贴切。
结构实例化后为什么会复制
结构也可以像类一样通过构造函数实例化,但实例创建出来以后,后续赋值和传参的行为会不同。因为结构是值类型,所以把一个结构赋给另一个变量时,复制的是当前值,而不是共享同一个对象引用。

Point p1 = new Point(10, 20);
Point p2 = p1; // 复制 p1 的值到 p2
p2.MoveTo(30, 40); // 只会影响 p2 的值
Console.WriteLine($"p1: ({p1.X}, {p1.Y})"); // 输出 (10, 20)
Console.WriteLine($"p2: ({p2.X}, {p2.Y})"); // 输出 (30, 40)
这里的关键不是“p2 指向了 p1”,而是 p2 拿到了一份独立副本。所以修改 p2 后,p1 不会跟着变化。
这也是结构最容易影响实际结果的地方:只要发生赋值、方法传参或返回值传递,就要先确认自己要的是“复制一份值”,还是“多个位置共享同一个对象”。如果是后者,通常类会更合适。
结构里可以定义哪些方法
结构不只是数据容器,它也可以拥有方法。常见写法包括实例方法、静态方法,以及运算符重载。
实例方法
实例方法绑定到具体结构实例上,可以访问并修改实例字段。
public void Print()
{
Console.WriteLine($"Point: ({X}, {Y})");
}
像 Print() 这种方法,适合放置与当前结构数据直接相关的行为。
静态方法
静态方法属于结构类型本身,不依赖某个具体实例,可以直接通过结构名调用。
public static bool IsOrigin(Point point)
{
return point.X == 0 && point.Y == 0;
}
// 调用
bool isOrigin = Point.IsOrigin(new Point(0, 0)); // true
这类方法适合做判断、转换、工厂方法或通用工具逻辑,尤其是在逻辑上不需要先创建调用者实例时。
运算符重载
如果一个结构天然适合做数值或几何运算,还可以重载运算符,让代码表达更自然。
// www.ja vascriptcn.com code example
public static Point operator +(Point a, Point b)
{
return new Point(a.X + b.X, a.Y + b.Y);
}
// 使用
Point p1 = new Point(10, 20);
Point p2 = new Point(30, 40);
Point p3 = p1 + p2; // 等同于 Point p3 = new Point(40, 60);
对坐标、向量、矩形边距这类类型来说,运算符重载能让结构更接近内置类型的使用体验。但前提是语义必须足够直观,避免为了“简洁”牺牲可读性。
结构和类到底有哪些关键区别
如果你在 struct 和 class 之间犹豫,通常可以先看下面几项差异:

- 类型语义:结构是值类型,类是引用类型。
- 赋值与传递:结构赋值或传参时,通常传递的是副本;类传递的是引用。
- 继承能力:结构不能从其他结构或类派生,但可以实现接口。
- 构造限制:原文指出,结构不允许显式定义无参数构造函数,而可以通过初始化器创建实例。
把它们放回实际开发里理解会更清楚:如果一个类型主要表示“小而固定的一组数据”,复制它本身没有歧义,而且你希望它具备值语义,那么结构更合适;如果这个类型需要共享状态、支持复杂继承层级,或者你希望多个变量操作的是同一个对象,那么类通常更稳妥。
什么时候更适合用结构
结构最适合承担“轻量数据模型”的角色,例如点、日期、范围、颜色、尺寸等。它们通常字段不多、含义明确,而且复制一份新值本身就是合理行为。
反过来说,如果一个类型需要频繁被修改并在多个地方共享,或者内部状态较复杂,仅仅因为“它数据不多”就用结构,往往会在复制行为上踩坑。判断时最实用的一条标准是:这个类型更像一个独立对象,还是更像一个值。
总结
struct 的核心不在于语法和 class 多像,而在于它是值类型。只要你理解了“赋值会复制、修改副本不会影响原值、可以包含方法但不能像类那样做继承扩展”,就能更准确地把结构用在坐标、日期和其他轻量数据场景里。









