结构类型是值类型,他可以声明常量、字段、方法、属性、索引器、运算符、实例构造函数、静态构造函数和嵌套类型。
1、结构类型是通过struct关键字定义的,例如
public stuct Poooo
{
//事件、属性、方法等
}
2、结构类型与类几乎共享所有相同的语法,但结构比类受到的限制更多。
尽管jie偶的静态字段可以初始化,结构实例字段声明还是不能使用初始值设定项。
结构不能声明默认的构造函数(无参数的构造函数)或析构函数。
结构的副本由编译器自动创建和销毁,因此不需要使用默认构造函数和析构函数。实际上,编译器通过为所有字段赋值默认值类实现默认构造函数。
结构不能从类或者其他结构继承。
3、结构具有一下特点:
a.结构是值类型,而类是引用类型。
b.向方法传递构造时,结构是通过传值方式传递的,而不是作为引用传递的。
c.与类不同,结构的实例化可以不使用New 运算符。
d.结构可以声明构造函数,但它必须带参数。
e.一个结构不能从另一个结构或类继承,而且不能作为类的基。所有的结构都直接继承自System.VlueType,后者继承自System.Object。
f.结构可以实现接口。
g.在结构中初始化实例字段是错误的。
现在引出问题
1、如果结构是值类型,但是结构成员可以是类,也就是说这个时候结构怎么分配内存呢?
结构的副本由编译器自动创建和销毁,也就是说结构在编译的时候就确定了存储空间了,不是在运行时到托管堆里面去分配内存。所以结构成员的类成员其实是保存的这个类的实例的地址。
2、那struct的new操作又是干什么的呢?
操作就是执行initobj指令,功能就是将位于指定地址的对象的所有字段初始化为空引用或适当的基元类型的0。如果是类的话实例化new的指令实际是newobj instance。所以class的new操作和struct的new操作是不一样的。
像下面这个结构
public
struct TestStruct
{
public int n;
public string s;
public StringBuilder sb;
当他
TestStruct
t = new TestStruct();
new的时结果是什么?其结果就是int类型被初始化为0,对象全部被置为null。
结论
struct的new操作是不执行分配内存操作的,其new操作只执行初始化数据操作。所以微软关于new关键字的用途的说法是不全面的。因为new还有一种只初始化数据而不在托管堆分配内存的功能。所以值类型和引用类型的实质我个人认为其实就是在什么时候分配内存和其传值调用方式。
注1
MSDN对new关键字用途的说法:
(1)new运算符
用于创建对象和调用构造函数。
(2)new修饰符
用于向基类成员隐藏继承成员。
(3)new约束
用于在泛型声明中约束可能用作类型参数的参数的类型。
注2
System.ValueType本来就是比较怪的一个东西。
.NET的编译器在处理他的时候是
1、把值存在计算堆栈上,这个是值类型的标准操作。
2、产生一个装箱操作如果初始化的是一个33这样的整数,那就装箱一个int32同理如果是3.3就是float。
3、执行一个stloc从计算堆栈的顶部弹出当前值并将其存储到指定索引处的局部变量列表中。
个人理解:System.ValueType更像是一个系统内置接口(当然应该不是真的接口)。而接口在平台当中不管是Java还是.NET都意味着一旦继承了这种系统内置接口,就会响应系统内部的某种处理或调用。