C#支持struct
结构体数据类型,和class
不同,结构体是存储在栈上的,它是值类型,结构体变量不能为被赋予null
;此外,结构体是隐式密封的(可以理解为声明为了sealed
),结构体虽然派生自System.Object
,但不能再派生其它结构。
用结构体封装一些数学计算中的数据类型有更好的性能,比如Unity中的Vector3
等就是通过结构体封装的,此外也可以用于网络通信方面。
这里我们直接看一个结构体声明和使用的例子。
struct Vector2
{
public float X;
public float Y;
public override string ToString()
{
return "{x:" + this.X + ", y:" + this.Y + "}";
}
}
上面代码中,我们声明了一个名为Vector2
的结构体,其中包含了成员变量X
和Y
。此外,ToString
则是一个覆盖System.Object
的方法,这里我们用于打印结构体的内容。
结构体是值类型,我们可以直接声明并赋值。
Vector2 vec2;
vec2.X = 1;
vec2.Y = 1;
这里要注意的是结构体的所有成员变量必须全部赋值后,结构体才可用,比如上面代码如果vec2.Y
没有赋值就尝试使用vec2
变量,会导致编译报错。
除此之外,C#也支持使用new
关键字创建结构体。
Vector2 vec2 = new Vector2();
实际上即使使用new
创建结构体,它也还是值类型,且是在栈内存上创建,而非堆内存。使用new
创建和直接声明使用的另一个区别是,new
创建的结构体会对成员变量进行默认初始化,比如上面例子中float
类型的成员变量会默认初始化为0
。
结构体是值类型,C#不允许为值类型创建无参构造函数,但带参数的构造函数是允许的。
struct Vector2
{
public float X;
public float Y;
public Vector2(float x, float y) : this()
{
this.X = x;
this.Y = y;
}
public override string ToString()
{
return "{x:" + this.X + ", y:" + this.Y + "}";
}
}
上面例子代码中,我们定义了一个带参数的构造函数,注意其中用到:this()
写法调用了无参构造函数,上面介绍过调用结构体的无参构造函数可以将结构体的成员变量初始化为默认值,这里也是相同的目的。