C#中的结构的功能非常强大,可以看做一个微型的类。可以包含构造函数(但有一些限制),常数,字段,方法,属性,索引器,运算符和嵌套类型等,甚至可以重写System.Object中的虚方法。
但struct和class还是有一些区别的:
- 类型:结构是值类型,类是引用类型
- 存储位置:结构存储在堆栈上,类存储在托管堆上
- 传递值:结构传递自身的副本,类传递引用的副本
- 构造函数:结构不能自定义无参的构造函数,而且在构造函数中要给所有的字段成员赋值
- 析构函数:结构不能自定义析构函数
- 初始化:结构声明中除非字段被声明成const 或 static,否则不能初始化
- 创建实例:结构在创建实例时可以不用new,而类必须用new
- 继承:结构不支持继承,只能实现接口
- 访问修饰符:结构不支持继承也就不能用protected和protected internal
- 结构声明中不允许使用abstract和sealed修饰符(结构不抽象,隐式密封)
一般情况下,我们很少使用结构,而且很多人也并不建议使用结构,但鉴于结构的这些特性和运行机制,合理正确的应用struct可以很好的提高性能,节约资源。
- 经常使用的类型,而且这些类型以数据为主不需要复杂的操作时声明成struct
- 一个类型如果数据量比较大而且会经常修改涉及到一些复杂操作,即使能用struct实现也要声明成类,因为类可以在以后的升级中更好的进行扩展
- 提供某些和非托管代码通信的兼容性
- 在.NET 框架中,System.Drawing命名空间中的有些元素,如:System.Drawing.Point、System.Guid就是实现为struct,而不是class,其原因也正在于以上介绍的各方面的权衡
博客园“越过林子”
结构是值类型,所以会影响性能,但根据使用结构的方式,这种影响可能是正面的,也可能是负面的。正面的影响是为结构分配内存时,速度非常快,因为它们将内 联或者保存在堆栈中。在结构超出了作用域被删除时,速度也很快。另一方面,只要把结构作为参数来传递或者把一个结构赋给另一个结构(例如A=B,其中A和B是结构),结构的所有内容就被复制,而对于类,则只复制引用。这样,就会有性能损失,根据结构的大小,性能损失也不同。注意,结构主要用于小的数据结构。但当把结构作为参数传递给方法时,就应把它作为ref参数传递,以避免性能损失——此时只传递了结构在内存中的地址,这样传递速度就与在类中的传递速度一样快了。另一方面,如果这样做,就必须注意被调用的方法可以改变结构的值。
博客园“佳园”
为在设计编程语言时将结构设计成无继承性?
其实类的继承是有相当的成本的 ——由于继承性,每个类需要用额外的数据空间来存储“继承图”来表示类的传承历史,
通俗地说来就是我们人类的家族家谱,里面存储着我们的祖宗十八代,只有这样我们才知道我们从哪里来的,而家谱肯定是需要额外的空间来存放的。
大家不要觉得这个存放“继承图”的空间很小,如果我们的程序需要用10000个点(Point)来存放游戏中的人物形体数据的话,
在一个场景中又有N个人,这个内存开销可不是小数目了。所以我们可以通过将点(Point)申明成 Struct而不是class来节约内存空间。