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)条方式分配存储空间,各个成员 ...
随机推荐
- asp.net 关闭子窗体 刷新主窗体
主窗体************************************************************************************ //原窗口保留,以对话框 ...
- 周赛-Integration of Polynomial 分类: 比赛 2015-08-02 08:40 10人阅读 评论(0) 收藏
Integration of Polynomial Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/O ...
- 山东理工大学第七届ACM校赛-飞花的鱼塘 分类: 比赛 2015-06-26 10:30 43人阅读 评论(0) 收藏
飞花的鱼塘 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 一日,飞花壕在稷下湖游玩,忽然,飞花巨有了一个养鱼的想法,于是,他大手 ...
- C#string常用函数总结
补充: 1:在C语言里 char占1个字节 而在C#,Java里char占两个字节 数据库里char 中汉占两个字节 字母数字占一个字 2:string ...
- 测试Animation大型动画文件拆分播放的可行性
最近遇到一个问题,剧情动画文件大了复杂了之后,每次修改输出很麻烦,导出fbx就需要20分钟. 所以我想到了一个比较好的解决方法,在unity这边解决.把动画文件拆分成若干份,然后赋予不同的层并行播放 ...
- python-dev无法安装
安装tensorflow之前需要先安装python-dev, 这个不能用pip install来安装,只能用sudo apt-get install来安装.安装后会发现还要先装另外两个东西,但是装这两 ...
- SpringMvc 使用poi导入导出Excel
Util类 package com.common.util; public class ExportUtil { private XSSFWorkbook wb = null; private XSS ...
- nltk安装及wordnet使用详解
环境:python2.7.10 首先安装pip 在https://pip.pypa.io/en/stable/installing/ 下载get-pip.py 然后执行 python get-pip. ...
- ios沙盒路径
http://www.cnblogs.com/ios-wmm/p/3299695.html iOS沙盒路径的查看和使用 NSString *path = NSHomeDirectory();//主目录 ...
- [YY]已知逆序列求原序列(二分,树状数组)
在看组合数学,看到逆序列这个概念.于是YY了一道题:已知逆序列,求出原序列. 例子: 元素个数 n = 8 逆序列 a={5,3,4,0,2,1,1,0} 则有原序列 p={4,8,6,2,5,1,3 ...