详述.NET里class和struct的异同

本文详细对比了C#中的结构与类的不同之处,包括它们的语法特性、内存分配方式、继承特性以及实例化过程等。通过这些比较,帮助读者理解何时选择使用结构,何时选择使用类。

结构与类共享几乎所有相同的语法,但结构比类受到的限制更多:
尽管结构的静态字段可以初始化,结构实例字段声明还是不能使用初始值设定项。
结构不能声明默认构造函数(没有参数的构造函数)或析构函数。
结构的副本由编译器自动创建和销毁,因此不需要使用默认构造函数和析构函数。
实际上,编译器通过为所有字段赋予默认值(参见默认值表)来实现默认构造函数。
结构不能从类或其他结构继承。
结构是值类型 -- 如果从结构创建一个对象并将该对象赋给某个变量,变量则包含结构的全部值。
复制包含结构的变量时,将复制所有数据,对新副本所做的任何修改都不会改变旧副本的数据。
由于结构不使用引用,因此结构没有标识 -- 具有相同数据的两个值类型实例是无法区分的。
C# 中的所有值类型本质上都继承自 ValueType,后者继承自 Object。
编译器可以在一个称为装箱的过程中将值类型转换为引用类型。

结构具有以下特点:
结构是值类型,而类是引用类型。
向方法传递结构时,结构是通过传值方式传递的,而不是作为引用传递的。
与类不同,结构的实例化可以不使用 new 运算符。
结构可以声明构造函数,但它们必须带参数。


一个结构不能从另一个结构或类继承,而且不能作为一个类的基。
所有结构都直接继承自 System.ValueType,后者继承自 System.Object。
结构可以实现接口。
在结构中初始化实例字段是错误的。

类与结构的差别
1. 值类型与引用类型
结构是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型
例如:int 对应System.int32 结构,string 对应 system.string 结构 ,通过使用结构可以创建更多的值类型
类是引用类型:引用类型在堆上分配地址 堆栈的执行效率要比堆的执行效率高
可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。
所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑
因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用 注:
1.虽然结构与类的类型不一样,可是他们的基类型都是对象(object),c#中所有类型的基类型都是object
2.虽然结构的初始化也使用了New 操作符可是结构对象依然分配在堆栈上而不是堆上
如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用
2.继承性
结构:不能从另外一个结构或者类继承,本身也不能被继承
虽然结构没有明确的用sealed声明,可是结构是隐式的sealed .
类:完全可扩展的,除非显示的声明sealed 否则类可以继承其他类和接口,自身也能被继承
注:虽然结构不能被继承 可是结构能够继承接口,方法和类继承接口一样
例如:结构实现接口
interface IImage
{
void Paint();
}
struct Picture : IImage
{
public void Paint()
{
// painting code goes here
}
private int x, y, z; // other struct members
}

3.内部结构:
结构:
没有默认的构造函数,但是可以添加构造函数
没有析构函数
没有 abstract 和 sealed(因为不能继承)
不能有protected 修饰符
可以不使用new 初始化
在结构中初始化实例字段是错误的
类:
有默认的构造函数
有析构函数
可以使用 abstract 和 sealed
有protected 修饰符
必须使用new 初始化

如何选择结构还是类
1. 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些
2. 结构表示如点、矩形和颜色这样的轻量对象
例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。
在此情况下,结构的成本较低。
3. 在表现抽象和多级别的对象层次时,类是最好的选择
4. 大多数情况下该类型只是一些数据时,结构时最佳的选择

`class` `struct` 都是用于定义复合数据类型的关键词,在某些语言中它们的功能相似,但在其他方面存在显著差异。以下是 C++ 中两者的异同点: ### 相同点 1. **成员变量函数**:两者都可以包含成员变量(属性)成员函数(方法),允许对封装的数据进行操作。 2. **构造与析构**:都支持自动生成默认构造函数、拷贝构造函数及赋值运算符,并可以显式地定义这些特殊成员函数;同时也能声明并实现用户自定义的构造函数以及析构函数。 3. **访问控制修饰词**:均可使用 public, protected 私有等关键字来设定类内部元素对外界可见性的限制规则,默认情况下 struct 成员为公有的而 class 的则相反。 4. **继承机制**:都能够作为基类型参与单继承或多层继承体系构建,通过派生新的子类别以扩展原有功能特性集。 5. **模板化结构体或类**:均能成为泛型编程的基本单元之一,借助于模板技术将自身设计成通用的形式供不同类型的实例创建所用。 6. **内存布局管理**:在大多数编译器上拥有几乎一致的对象模型描述方式——即字段按照源码顺序依次排列存放于连续地址空间内,同时也遵守相同的对齐约束条件。 7. **作用域解析运算符 ::** :当需要指明某个特定命名空间内的静态成员或是全局范围内存在的同名实体时,则一律采用双冒号符号表示法来进行限定说明。 8. **友元声明**:二者皆具备让外部非成员函数直接存取其保护级甚至私密级别的资源权限的能力,只需利用 friend 关键字加以标注即可达成目的。 9. **常量表达式 constexpr 构造器**:现代标准还赋予了这两种聚合体形式能够立即初始化自身状态的权利,只要所有构成要素本身也满足即时求值的要求就可以做到这一点。 ### 区别 尽管上述提到许多共通之处,但仍然存在着几个关键的不同之处使得选择其中一种而非另一种变得重要起来: #### 默认访问级别 - 对于 struct 而言,默认情况下它的成员都是公开 (public) 访问的; - 反之对于 class 来说,默认状态下所有东西都被设为了私有(private),除非特别指定改变这种状况。 ```cpp // Struct 示例 - 默认公共访问 struct Point { int x; // 公开访问 int y; }; Point p{10}; // 合法语法,因为x,y 是 public ``` ```cpp // Class 示例 - 默认私有访问 class Rectangle { double width; // 私有访问 double height; public: void setSize(double w, double h); }; Rectangle r; r.width = 10; // 错误:width 是 private 类型 ``` #### 内存分配习惯 虽然这不是强制规定的区别特征,但从传统意义上讲 structs 更倾向于被当作简单的“纯数据容器”看待,很少涉及复杂逻辑处理业务场景的应用场合下出现;classes 则通常用来建模现实世界的事物及其交互模式,因此更可能携带较为丰富的算法流程在面运作着。 此外值得注意的是,在某些高级应用场景比如 COM 编程或者 WinAPI 函数调用过程中,由于历史遗留原因导致某些地方只能接受特定形态如 structure 形式的输入参数传递过来的信息内容而已! 综上所述,当我们面对具体项目需求时应根据实际情况权衡利弊再做定夺是否选用某一方还是混合搭配使用它们俩来完成任务目标吧~
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值