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)条方式分配存储空间,各个成员 ...
随机推荐
- wpf的研究和反思
WPF的研究和反思 目前是否适合使用wpf WPF(Windows Presentation Foundation)是微软推出的基于Windows Vista的用户界面框架,属于.NET F ...
- Entity Framework 第四篇 优化SQL查询
Expression<Func<TEntity, bool>>与Func<TEntity, bool>的异同 public IList<TEntity> ...
- hdu 4002 Find the maximum
Find the maximum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) ...
- apahce
基本的操作方法:本文假设你的apahce安装目录为/usr/local/apache2,这些方法适合任何情况 apahce启动命令:推荐/usr/local/apache2/bin/apachectl ...
- address
http://www.chsi.com.cn/ 学历查询网 http://www.gzzk.cc/ 广州自考网
- 给table设置滚动条
<div scroll="no" style="width:1200px;overflow-x:scroll;overflow-y:hidden"> ...
- 【leetcode❤python】226. Invert Binary Tree
#-*- coding: UTF-8 -*- # Definition for a binary tree node.# class TreeNode(object):# def __init ...
- 学习html5第一天
HTMl5作为web标准的一种,在2004年诞生,web超文本应用技术工作组WHATWG将它发展起来,W3C由开始的不赞同到与WHATWG共同合作,并在2015年开始推广.并随着浏览器的不断支持和兼容 ...
- unity3d 游戏对象消失三种方法的区别(enabled/Destroy/active)
gameObject.renderer.enabled //是控制一个物体是否在屏幕上渲染或显示 而物体实际还是存在的 只是想当于隐身 而物体本身的碰撞体还依然存在的 GameObject.Destr ...
- CentOS 7 (无盘安装)PXE服务器的搭建(失败求助版)
折腾了一天半,PXE无盘服务器以暂时失败而告终. 基本原理 1. 首先客户端主机需要支持PXE,大部分主板都支持. 2. PXE服务器需要安装DHCP.TFTP.FTP服务. 3. DHCP服务用来给 ...