先概述一下:

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的更多相关文章

  1. 使用struct处理二进制

    有的时候需要用python处理二进制数据,比如,存取文件.socket操作时.这时候,可以使用python的struct模块来完成. struct模块中最重要的三个函数是pack(), unpack( ...

  2. golang struct扩展函数参数命名警告

    今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...

  3. go-使用 unsafe 修改 struct 中的 field 的值

    以下是方法,不要纠结原理,等东西积累多了,你才有能力纠结原理: 首先,你需要有一个这样的函数,这是在 nsq 的源码里直接抄过来的: func unsafeValueOf(val reflect.Va ...

  4. C语言中struct位域的定义和使用

    位域的定义和使用 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又 ...

  5. C# Struct结构体里数组长度的指定

    typedef struct Point{ unsigned short x; unsigned short y; }mPoint;//点坐标 typedef struct Line{ mPoint ...

  6. C 语言Struct 实现运行类型识别 RTTI

    通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型.c++通过下面两个操作符提供RTTI. (1)typeid:返回指针或引用所指对象的实际类型.    (2)dynamic_cast: ...

  7. 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版本的代码,但 ...

  8. 字节流与数据类型的相互转换---使用struct模块

    字节流与数据类型的相互转换---使用struct模块 http://blog.csdn.net/Sunboy_2050/article/details/5974029 Python是一门非常简洁的语言 ...

  9. 窥探Swift之别具一格的Struct和Class

    说到结构体和类,还是那句话,只要是接触过编程的小伙伴们对这两者并不陌生.但在Swift中的Struct和Class也有着令人眼前一亮的特性.Struct的功能变得更为强大,Class变的更为灵活.St ...

  10. struct 大小计算

    结构体是一种复合数据类型,通常编译器会自动的进行其成员变量的对齐,已提高数据存取的效率.在默认情况下,编译器为结构体的成员按照自然对齐(natural alignment)条方式分配存储空间,各个成员 ...

随机推荐

  1. asp.net 关闭子窗体 刷新主窗体

    主窗体************************************************************************************ //原窗口保留,以对话框 ...

  2. 周赛-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 ...

  3. 山东理工大学第七届ACM校赛-飞花的鱼塘 分类: 比赛 2015-06-26 10:30 43人阅读 评论(0) 收藏

    飞花的鱼塘 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 一日,飞花壕在稷下湖游玩,忽然,飞花巨有了一个养鱼的想法,于是,他大手 ...

  4. C#string常用函数总结

    补充:             1:在C语言里 char占1个字节 而在C#,Java里char占两个字节 数据库里char 中汉占两个字节 字母数字占一个字             2:string ...

  5. 测试Animation大型动画文件拆分播放的可行性

    最近遇到一个问题,剧情动画文件大了复杂了之后,每次修改输出很麻烦,导出fbx就需要20分钟. 所以我想到了一个比较好的解决方法,在unity这边解决.把动画文件拆分成若干份,然后赋予不同的层并行播放 ...

  6. python-dev无法安装

    安装tensorflow之前需要先安装python-dev, 这个不能用pip install来安装,只能用sudo apt-get install来安装.安装后会发现还要先装另外两个东西,但是装这两 ...

  7. SpringMvc 使用poi导入导出Excel

    Util类 package com.common.util; public class ExportUtil { private XSSFWorkbook wb = null; private XSS ...

  8. nltk安装及wordnet使用详解

    环境:python2.7.10 首先安装pip 在https://pip.pypa.io/en/stable/installing/ 下载get-pip.py 然后执行 python get-pip. ...

  9. ios沙盒路径

    http://www.cnblogs.com/ios-wmm/p/3299695.html iOS沙盒路径的查看和使用 NSString *path = NSHomeDirectory();//主目录 ...

  10. [YY]已知逆序列求原序列(二分,树状数组)

    在看组合数学,看到逆序列这个概念.于是YY了一道题:已知逆序列,求出原序列. 例子: 元素个数 n = 8 逆序列 a={5,3,4,0,2,1,1,0} 则有原序列 p={4,8,6,2,5,1,3 ...