可以把结构看做缩小的类,适合于把一些数据组合起来的场合。结构是值类型,因此new运算符与类和其他引用类型的工作方式不同。new运算符不是分配堆中的内存,而是调用默认的构造函数,在堆栈上把所有的字段初始化为默认值。对于下边的语句:
pt.length = 4;
pt.width = 2;
如果TestStruct 是一个类,那么就会产生一个编译错误,因为pt包含一个未初始化的引用(未指向任何地方),所以不能给其字段赋值。但是对于结构,声明变量实际上是为整个结构分配栈中的空间,所以就可以赋值了。但注意下边语句会产生一个编译错误,
Double d = pt.length;
这是因为虽然已经为结构分配的空间,但是变量并没有初始化。只有调用了new运算符或者给所有的字段分别赋值,结构才完成了初始化,也只有在此之后才能调用结构提供的方法。如下语句会产生一个编译错误:
pt.print();
由于结构是值类型,因此把结构作为参数来传递或把一个结构赋给另一个结构,结构中的所有内容都会被复制,这样一来,就会有性能上的损失,如果把结构做为ref参数传递,就可以避免性能损失,因为只传递了结构在内存中的地址。
不能从一个结构中继承,也不能从任何类中派生。特别的一点是结构派生于System.Objec,因此结构能重写ToString()方法。在结构中声明方法的方式和在类中是一样的,但是不能把结构的任何成员声明为virtual(结构不允许被继承),也不能把结构声明为abstract或把结构显式的声明为sealed(结构总是隐式密封的)。
不能为结构定义无参数的构造函数。在结构的定义中,也不能提供字段的初始值,以此来绕过默认构造函数,事实上默认的构造函数总是隐式地给出,即使提供了其他带参的构造函数。