C# - 结构体 (Struct)
在 C# 中,struct
是一种值类型数据类型,表示数据结构。它可以包含参数化构造函数、静态构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型。
struct
可用于存储不需要继承的小数据值,例如坐标点、键值对和复杂数据结构。
结构体声明
使用 struct
关键字声明结构体。结构体及其成员的默认修饰符是 internal。
以下示例为图形声明了一个结构体 Coordinate
。
struct Coordinate
{
public int x;
public int y;
}
可以像原始类型变量一样,使用或不使用 new
运算符创建 struct
对象。
struct Coordinate
{
public int x;
public int y;
}
Coordinate point = new Coordinate();
Console.WriteLine(point.x); //output: 0
Console.WriteLine(point.y); //output: 0
上面使用 new
关键字创建了一个 Coordinate
结构体的对象。它调用了 struct
的默认无参构造函数,该构造函数将所有成员初始化为其指定数据类型的默认值。
如果声明 struct
类型的变量而没有使用 new
关键字,则它不会调用任何构造函数,因此所有成员都将保持未赋值状态。因此,您必须在访问每个成员之前为它们赋值,否则会产生编译时错误。
struct Coordinate
{
public int x;
public int y;
}
Coordinate point;
Console.Write(point.x); // Compile time error
point.x = 10;
point.y = 20;
Console.Write(point.x); //output: 10
Console.Write(point.y); //output: 20
结构体中的构造函数
struct
不能包含无参构造函数。它只能包含参数化构造函数或静态构造函数。
struct Coordinate
{
public int x;
public int y;
public Coordinate(int x, int y)
{
this.x = x;
this.y = y;
}
}
Coordinate point = new Coordinate(10, 20);
Console.WriteLine(point.x); //output: 10
Console.WriteLine(point.y); //output: 20
您必须在参数化构造函数中包含 struct
的所有成员,并将参数赋值给成员;否则,如果任何成员未赋值,C# 编译器将发出编译时错误。
结构体中的方法和属性
struct
可以包含属性、自动实现的属性、方法等,与类相同。
struct Coordinate
{
public int x { get; set; }
public int y { get; set; }
public void SetOrigin()
{
this.x = 0;
this.y = 0;
}
}
Coordinate point = Coordinate();
point.SetOrigin();
Console.WriteLine(point.x); //output: 0
Console.WriteLine(point.y); //output: 0
以下 struct
包含静态方法。
struct Coordinate
{
public int x;
public int y;
public Coordinate(int x, int y)
{
this.x = x;
this.y = y;
}
public static Coordinate GetOrigin()
{
return new Coordinate();
}
}
Coordinate point = Coordinate.GetOrigin();
Console.WriteLine(point.x); //output: 0
Console.WriteLine(point.y); //output: 0
结构体中的事件
结构体可以包含事件,以通知订阅者有关某个操作。以下 struct
包含一个事件。
struct Coordinate
{
private int _x, _y;
public int x
{
get{
return _x;
}
set{
_x = value;
CoordinatesChanged(_x);
}
}
public int y
{
get{
return _y;
}
set{
_y = value;
CoordinatesChanged(_y);
}
}
public event Action<int> CoordinatesChanged;
}
上述结构体包含 CoordinatesChanged
事件,当 x
或 y
坐标改变时将触发该事件。以下示例演示了如何处理 CoordinatesChanged
事件。
class Program
{
static void Main(string[] args)
{
Coordinate point = new Coordinate();
point.CoordinatesChanged += StructEventHandler;
point.x = 10;
point.y = 20;
}
static void StructEventHandler(int point)
{
Console.WriteLine("Coordinate changed to {0}", point);
}
}
struct
是值类型,因此它比类对象更快。当您只想存储数据时,请使用 struct。通常,结构体非常适合游戏编程。然而,传输类对象比结构体更容易。因此,当您通过网络或其他类传递数据时,请不要使用 struct。
总结
struct
可以包含构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型。struct
不能包含无参构造函数或析构函数。struct
可以像类一样实现接口。struct
不能继承其他结构体或类,也不能作为类的基类。struct
成员不能指定为 abstract、sealed、virtual 或 protected。
- 结构体详解
- Eric Lippert 关于 struct 的博客
- 选择类和结构体
- 结构体和类的区别