struct和class
先概述一下:
1、C# 是纯面向对象语言,struct 与 class 都是继承Object,都是对象。struct 是值类型、class 是引用类型。
2、struct是值类型,在Stack上分配地址,在方法调用退出后会自动释放资源,class 是引用类型,在托管Heap上分配地址,必须GC运行清除对象垃圾。Stack的执行效率比Heap的执行效率高,但是Stack的资源很有限。因此,struct只适合小对象,不适合大的、逻辑复杂的对象。
3、struct 是值类型,赋值的时候是“整体拷贝”,class 是引用类型,赋值的时候是 复制引用。
4、struct的设计是为了封装数据,而class 的设计是为了封装数据和行为。它们的设计目的不同,导致了它们有很大的区别。
5、struct 不能继承(当然struct隐式地继承了Object),可以实现接口,也不能被继承(是隐式的sealed)。class 可以继承或者被继承。
6、struct 没有默认的构造方法,但是可以添加构造方法;没有析构方法(因为分配在Stack上);没有abstract ,sealed,virtual,protected(因为不能被继承);在struct内不能对字段赋值,所有字段为默认值;可以不使用new 进行初始化,声明的变量不为null。class 有默认的构造方法和析构方法;完全可扩展(继承和被继承);必须使用new初始化,否则声明的变量为null。
7、可以认为struct是轻量级的class,struct适合下列情况:
小的对象,不包含复杂的业务逻辑和行为,只是表现一些数据。
不表现抽象和多级别的层次结构。
思考:问什么struct与class 会有上面的区别?
这是因为struct和class的使用场景不同,也就是说,解决的问题不同,设计理念不同。因为struct的使用场景是,小对象、只是表现一些数据,不包含复杂的业务逻辑,不表现抽象和多级别的层次结构。因为是小对象,把struct 分配在栈上,进行整体拷贝,代价不大,不需要构造方法和析构方法。因为不表现抽象和多级别的层次结构,struct 不需要支持继承等等。
class和struct最本质的区别是class是引用类型,而struct是值类型,它们在内存中的分配情况有所区别。
什么是class?
class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、属性、构造函数、索引器、操作符等。在.NET中,所有的类都最终继承自System.Object类,因此是一种引用类型,也就是说,new一个类的实例时,在堆栈(stack)上存放该实例在托管堆(managed heap)中的地址,而实例的值保存在托管堆(managed heap)中。
什么是struct?
struct(结构)是一种值类型,用于将一组相关的变量组织为一个单一的变量实体 。所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例在创建时分配在线程的堆栈(stack)上,它本身存储了值。所以在使用struct时,我们可以将其当作int、char这样的基本类型类对待。
1,class 是引用类型,structs是值类型
既然class是引用类型,class可以设为null。但是我们不能将struct设为null,因为它是值类型。
namespace Ax
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
structA x = null; //错误:无法将 Null 转换成“structA”,因为它是一种不可以为null 值的类型
classA y = null;
}
}
}
public struct structA
{
public int A;
}
public class classA
{
public int A;
}
2,当你实例化一个class,它将创建在堆上。而你实例化一个struct,它将创建在栈上
3,你使用的是一个对class实例的引用。而你使用的不是对一个struct的引用。(而是直接使用它们)
4,当我们将class作为参数传给一个方法,我们传递的是一个引用。struct传递的是值而非引用。
5,structs 不可以有初始化器,class可以有初始化器。
public struct structA
{
//public int A = 90; //错误:“structA.A”: 结构中不能有实例字段初始值
public int A;
}
public class classA
{
public int A = 90;
}
6,Classes 可以有明显的无参数构造器,但是Struct不可以
public struct structA
{
//public int A = 90; //错误:“structA.A”: 结构中不能有实例字段初始值
public int A;
//public structA() //错误:结构不能包含显式的无参数构造函数
//{
// this.A = 0;
//}
public structA(int paraA) //ok
{
this.A = paraA;
}
}
public class classA
{
public int A = 90;
public classA()
{
this.A = 90;
}
}
7,类使用前必须new关键字实例化,Struct不需要
public Form3()
{
InitializeComponent();
//structA x = null; //错误 :无法将 Null 转换成“structA”,因为它是一种不可以为 null 值的类型
structA x;
x.A = 8;
structA x2 = new structA();
x2.A = 32;
classA y = null;
classA y1 = new classA();
y1.A = 4;
classA y2;
//y2.A = 5;//错误:使用了未赋值的局部变量“y2”
}
8,class支持继承和多态,Struct不支持. 注意:但是Struct 可以和类一样实现接口
9,既然Struct不支持继承,其成员不能以protected 或Protected Internal 修饰
10,Class的构造器不需要初始化全部字段,Struct的构造器必须初始化所有字段
public struct structA
{
public int A;
public int B;
public structA(int paraA, int paraB) //ok
{
this.A = paraA;
this.B = paraB;
}
//public structA(int paraA) //ok
//{
// this.A = paraA;
// this.B = paraA;
//}
//public structA(int paraA, int paraB) //错误:在控制返回调用方之前,字段“structA.B”必须被完全赋值
//{
// this.A = paraA;
//}
}
public class classA
{
public int A = 90;
public int B;
public classA()
{
this.A = 90;
}
}
11,Class可以定义析构器,但是Struct不可以
12,Class比较适合大的和复杂的数据,Struct适用于作为经常使用的一些数据组合成的新类型。
适用场合:Struct有性能优势,Class有面向对象的扩展优势。
用于底层数据存储的类型设计为Struct类型,将用于定义应用程序行为的类型设计为Class。如果对类型将来的应用情况不能确定,应该使用Class。
struct和class的更多相关文章
- 使用struct处理二进制
有的时候需要用python处理二进制数据,比如,存取文件.socket操作时.这时候,可以使用python的struct模块来完成. struct模块中最重要的三个函数是pack(), unpack( ...
- golang struct扩展函数参数命名警告
今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...
- go-使用 unsafe 修改 struct 中的 field 的值
以下是方法,不要纠结原理,等东西积累多了,你才有能力纠结原理: 首先,你需要有一个这样的函数,这是在 nsq 的源码里直接抄过来的: func unsafeValueOf(val reflect.Va ...
- C语言中struct位域的定义和使用
位域的定义和使用 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又 ...
- C# Struct结构体里数组长度的指定
typedef struct Point{ unsigned short x; unsigned short y; }mPoint;//点坐标 typedef struct Line{ mPoint ...
- C 语言Struct 实现运行类型识别 RTTI
通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型.c++通过下面两个操作符提供RTTI. (1)typeid:返回指针或引用所指对象的实际类型. (2)dynamic_cast: ...
- VC++ : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall std::basic_string<wchar_t,struct std::char_traits<wchar_t>
最近学习Google Breakpad,将其用在了自己的项目中,编译的版本为VS2010,没有什么问题.但是为了和之前的程序兼容,需要使用VS2008版本的程序,于是又编译了VS2008版本的代码,但 ...
- 字节流与数据类型的相互转换---使用struct模块
字节流与数据类型的相互转换---使用struct模块 http://blog.csdn.net/Sunboy_2050/article/details/5974029 Python是一门非常简洁的语言 ...
- 窥探Swift之别具一格的Struct和Class
说到结构体和类,还是那句话,只要是接触过编程的小伙伴们对这两者并不陌生.但在Swift中的Struct和Class也有着令人眼前一亮的特性.Struct的功能变得更为强大,Class变的更为灵活.St ...
- struct 大小计算
结构体是一种复合数据类型,通常编译器会自动的进行其成员变量的对齐,已提高数据存取的效率.在默认情况下,编译器为结构体的成员按照自然对齐(natural alignment)条方式分配存储空间,各个成员 ...
随机推荐
- php编译器
WordPress http://pan.baidu.com/s/1eQnOnv0 epp3: http://pan.baidu.com/s/1pJKFOD1 配合xampp: http://pan. ...
- Unity5 Standard自发光材质无效解决方法
受光物和发光物都要勾选Static才会有效. 如果不够选静态就是用HDR光照,需要相机勾选HDR 所以如果是动态的物体真实发光,Unity依旧无法支持
- Uva 1220,Hali-Bula 的晚会
题目链接:https://uva.onlinejudge.org/external/12/1220.pdf 题意: 公司n个人,形成一个数状结构,选出最大独立集,并且看是否是唯一解. 分析: d(i) ...
- HTML 5 Web Sockets应用初探
转载不错的http://developer.51cto.com/art/201008/217874.htm
- #ifdef DEBUG的理解
今天看到一段代码,对ifdef的概念比较模糊,于是去学习了一下,找到一个很好的解释,如下: 在工程设置里有一些设置会对该工程自动产生一系列的宏,用以控制程序的编译和运行.就好象楼上说的一样,如果你把代 ...
- Mysql-学习笔记(==》事件 十二)
事件 计划任务(定期定时执行) -- 查看当前mysql数据库是否开启时间功能,默认关闭SHOW VARIABLES LIKE 'event_scheduler'; -- event_schedule ...
- shell与kernel的理解 转载
Shell 的英文释义是外壳,与 kernel 内核名词遥相呼应,一外一内,一壳一核.内核就像瑞士银行的金库,存放着客户的黄金等众多的(硬件)资产,闲杂人等(包括客户)当然是严格禁止入内的,而作为客户 ...
- deep-learning-frameworks
From: http://venturebeat.com/2015/11/14/deep-learning-frameworks/ Here’s a rundown of some other not ...
- ADC驱动器或差分放大器设计指南
作为应用工程师,我们经常遇到各种有关差分输入型高速模数转换器(ADC)的驱动问题.事实上,选择正确的ADC驱动器和配置极具挑战性.为了使鲁棒性ADC电路设计多少容易些,我们汇编了一套通用“路障”及解决 ...
- 【Protle99SE】PCB中各层的含义【小汇】
忽然发现,对solder和paste,layer和plane这两对有些糊涂了,摘录网络中的文章如下: [http://www.360doc.com/content/10/0608/15/514342_ ...