先概述一下:

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. wpf的研究和反思

    WPF的研究和反思 目前是否适合使用wpf      WPF(Windows Presentation Foundation)是微软推出的基于Windows Vista的用户界面框架,属于.NET F ...

  2. Entity Framework 第四篇 优化SQL查询

    Expression<Func<TEntity, bool>>与Func<TEntity, bool>的异同 public IList<TEntity> ...

  3. hdu 4002 Find the maximum

    Find the maximum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) ...

  4. apahce

    基本的操作方法:本文假设你的apahce安装目录为/usr/local/apache2,这些方法适合任何情况 apahce启动命令:推荐/usr/local/apache2/bin/apachectl ...

  5. address

    http://www.chsi.com.cn/ 学历查询网 http://www.gzzk.cc/ 广州自考网

  6. 给table设置滚动条

    <div  scroll="no" style="width:1200px;overflow-x:scroll;overflow-y:hidden"> ...

  7. 【leetcode❤python】226. Invert Binary Tree

    #-*- coding: UTF-8 -*- # Definition for a binary tree node.# class TreeNode(object):#     def __init ...

  8. 学习html5第一天

    HTMl5作为web标准的一种,在2004年诞生,web超文本应用技术工作组WHATWG将它发展起来,W3C由开始的不赞同到与WHATWG共同合作,并在2015年开始推广.并随着浏览器的不断支持和兼容 ...

  9. unity3d 游戏对象消失三种方法的区别(enabled/Destroy/active)

    gameObject.renderer.enabled //是控制一个物体是否在屏幕上渲染或显示 而物体实际还是存在的 只是想当于隐身 而物体本身的碰撞体还依然存在的 GameObject.Destr ...

  10. CentOS 7 (无盘安装)PXE服务器的搭建(失败求助版)

    折腾了一天半,PXE无盘服务器以暂时失败而告终. 基本原理 1. 首先客户端主机需要支持PXE,大部分主板都支持. 2. PXE服务器需要安装DHCP.TFTP.FTP服务. 3. DHCP服务用来给 ...