C#中的结构
结构
问题一:什么是结构?
结构(struct)是自定义的一种数据类型,与类(class)很相似,具有数据成员和函数成员。 结构与类的区别是:
- 类是引用类型,结构是值类型;
- 结构是隐式的、密封的,因此不能像类那样被派生。
声明结构的语法与声明类相似:
1 2 3 4 | struct StructName
{
MemberDeclarations
}
|
值类型的结构
既然是值类型,那么结构变量就含有自己的数据,因此:
- 结构类型的变量不能为null;
- 两个结构变量不能引用同一对象。
对比结构和类的代码: 类的声明:
1 2 3 4 5 | class DemoClass { public int x; public int y; } |
结构的声明:
1 2 3 4 5 | struct DemoStruct { public x; public y; } |
给结构赋值
class2 = class1;
上面这个给类赋值的语句,只是复制了数值的引用,即这样赋值以后,class1和class2这两个引用,都是指向堆中的相同对象。而像下面这样给结构赋值的话:
struct2 = struct1;
struct1的数值会直接复制到struct2中,此时在栈中存在struct1和struct2两个内容相同但各自完全独立的对象。
结构类型的构造函数
结构,可以有实例构造函数,也可以有静态构造函数,但是不允许有析构函数。
实例构造函数
编译器会隐式的提供一个默认构造函数,将结构中的每个成员设为该类型的默认值。 与类不同,如果手动为类创建构造函数,那么隐式的无参数构造函数就无效了。但是结构的默认构造函数不能删除或重定义,即使手动编写结构的构造函数,默认的无参数构造函数仍然有效。 实例化结构与类一样,要用new语法,例如:
1 2 3 4 5 6 7 8 9 10 11 12 | struct DemoStruct { whatever inside; } class Program { static void Main() { DemoStruct s1 = new DemoStruct(); //隐式构造函数 DemoStruct s2 = new DemoStruct( 5, 10 ); //自定义构造函数 } } |
静态构造函数
结构类型的静态构造函数与类是相同的,静态构造函数创建并初始化静态数据成员,不能引用实例成员。
在结构中不允许使用字段初始化语句
例如,下面的语句不能编译通过:
1 2 3 4 | struct Simple { public int = 10; //这是不可以的! } |
密封
结构是密封的,不允许派生,不支持继承,不能使用以下修饰符:
protected
internal
abstract
virtual
结构是派生自System.ValueType,而System.ValueType派生自Object。 可以用于结构成员并与继承相关的关键字是new和override,当创建于结构的基类System.ValueType的成员相同名称的成员时可以使用这两个修饰符。
装箱和拆箱
与其它值类型一样,如果要将结构实例作为引用类型的对象,就必须进行装箱。
结构作为返回值和参数
- 当结构作为返回值时,将创建一个副本,从函数成员返回。
- 当结构作为值参数时,也是创建一个副本,用于方法执行中。
- 把结构作为ref或out参数的话,传入方法的是结构的一个引用,方法可以修改原结构数据成员。
关于结构的其它注意事项
如果不打算包含方法,那么可以用结构代替类,因为结构的实例开销比较小。但是要注意装箱和拆箱的代价更大,所以如果需要引用类型,也许还是应该考虑使用类。
预定义的简单类型,如int
、short
、long
等等,尽管在.Net和C#中被视为原始类型,但其实他们在.Net中都实现为结构。
可以声明分部结构(使用partial关键字),这与类是相同的。
与类一样,可以实现接口。