首页 > 编程语言 >c#学习笔记-----------------值类型和引用类型

c#学习笔记-----------------值类型和引用类型

时间:2023-08-07 18:25:35浏览次数:43  
标签:存储 c# 托管 ----------------- 对象 线程 引用 类型

基本概念

CLR支持两只类型:引用类型值类型

这是.NET语言的基础和关键,他们从类型定义、实例创建、参数传递,到内存分配都有所不同。

 下图清晰了展示了.NET中类型分类,

值类型主要是一些简单的、基础的数据类型,

引用类型主要用于更丰富的、复杂的、复合的数据类型。

 

内存结构

值类型和引用类型最根源的区别就是其内存分配的差异,在这之前首先要理解CLR的内存中两个重要的概念:

Stack 栈:线程栈,由操作系统管理,存放值类型、引用类型变量(就是引用对象在托管堆上的地址)。栈是基于线程的,也就是说一个线程会包含一个线程栈,线程栈中的值类型在对象作用域结束后会被清理,效率很高。

GC Heap托管堆:进程初始化后在进程地址空间上划分的内存空间,存储.NET运行过程中的对象,所有的引用类型都分配在托管堆上,托管堆上分配的对象是由GC来管理和释放的。托管堆是基于进程的,当然托管堆内部还有其他更为复杂的结构,有兴趣的可以深入了解。

结合下图理解,变量a及其值3都是存储在栈上面。变量b在栈上存储,其值指向字符串“123”的托管堆对象地址(字符串是引用类型,字符串对象是存储在托管堆上面。字符串是一个特殊的引用类型,后面文章会专门探讨)”

 

 

值类型只需要⼀段单独的内存,⽤于存储实际的数据,(单独定义的时候放在栈中)

引⽤类型需要两段内存

第⼀段存储实际的数据,它总是位于堆中

第⼆段是⼀个引⽤,指向数据在堆中的存放位置

注意:

当我们使⽤引⽤类型赋值的时候,

其实是赋值的引⽤类型的引⽤

如果数组是⼀个值类型的数组,那么数组中直接存储值,

如果是⼀个引⽤类型的数组(数 组中存储的是引⽤类型),那么数组中存储的是引⽤(内存地址)

 

1. 值类型和引用类型的区别?

值类型包括简单类型、结构体类型和枚举类型,引用类型包括自定义类、数组、接口、委托等。

  • 1、赋值方式:将一个值类型变量赋给另一个值类型变量时,将复制包含的值。这与引用类型变量的赋值不同,引用类型变量的赋值只复制对象的引用(即内存地址,类似C++中的指针),而不复制对象本身。
  • 2、继承:值类型不可能派生出新的类型,所有的值类型均隐式派生自 System.ValueType。但与引用类型相同的是,结构也可以实现接口。
  • 3、null:与引用类型不同,值类型不可能包含 null 值。然而,可空类型允许将 null 赋给值类型(他其实只是一种语法形式,在clr底层做了特殊处理)。
  • 4、每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值,值类型初始会默认为0,引用类型默认为null。
  • 5、值类型存储在栈中,引用类型存储在托管堆中。

2. 结构和类的区别?

结构体是值类型,类是引用类型,主要区别如题1。其他的区别:

  • 结构不支持无惨构造函数,不支持析构函数,并且不能有protected修饰;
  • 结构常用于数据存储,类class多用于行为;
  • class需要用new关键字实例化对象,struct可以不适用new关键字;
  • class可以为抽象类,struct不支持抽象;

3. delegate是引用类型还是值类型?enum、int[]和string呢?

enum枚举是值类型,其他都是引用类型。

4. 堆和栈的区别?

线程堆栈:简称栈 Stack
托管堆: 简称堆 Heap
  • 值类型大多分配在栈上,引用类型都分配在堆上;
  • 栈由操作系统管理,栈上的变量在其作用域完成后就被释放,效率较高,但空间有限。堆受CLR的GC控制;
  • 栈是基于线程的,每个线程都有自己的线程栈,初始大小为1M。堆是基于进程的,一个进程分配一个堆,堆的大小由GC根据运行情况动态控制;

6.“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?

结构是值类型,有两种情况会分配在对上面:

  • 结构作为class的一个字段或属性,会随class一起分配在堆上面;
  • 装箱后会在堆中存储,尽量避免值类型的装箱,值类型的拆箱和装箱都有性能损失,下一篇会重点关注;

7. 理解参数按值传递?以及按引用传递?

  • 按值传递:对于值类型传递的它的值拷贝副本,而引用类型传递的是引用变量的内存地址,他们还是指向的同一个对象。
  • 按引用传递:通过关键字out和ref传递参数的内存地址,值类型和引用类型的效果是相同的。

8. out 和 ref的区别与相同点?

  • out 和 ref都指示编译器传递参数地址,在行为上是相同的;
  • 他们的使用机制稍有不同,ref要求参数在使用之前要显式初始化,out要在方法内部初始化;
  • out 和 ref不可以重载,就是不能定义Method(ref int a)和Method(out int a)这样的重载,从编译角度看,二者的实质是相同的,只是使用时有区别;

9. C#支持哪几个预定义的值类型?C#支持哪些预定义的引用类型?

值类型:整数、浮点数、字符、bool和decimal

引用类型:Object,String

10. 有几种方法可以判定值类型和引用类型?

简单来说,继承自System.ValueType的是值类型,反之是引用类型。

11. 说说值类型和引用类型的生命周期?

值类型在作用域结束后释放。

引用类型由GC垃圾回收期回收。这个答案可能太简单了,更详细的答案在后面的文章会说到。

12. 如果结构体中定义引用类型,对象在内存中是如何存储的?例如下面结构体中的class类 User对象是存储在栈上,还是堆上?

public struct MyStruct 
{ 
    public int Index; 
    public User User; 
}

MyStruct存储在栈中,其字段User的实例存储在堆中,MyStruct.User字段存储指向User对象的内存地址。

 

 

标签:存储,c#,托管,-----------------,对象,线程,引用,类型
From: https://www.cnblogs.com/misakayoucn/p/17612143.html

相关文章

  • FindByNameAsync vs FindByIdAsync vs FindByEmailAsync vs FindByLoginAsync
    InASP.NETIdentity,UserManagerisacoreclassthatprovidesasetofAPIstomanageuseraccounts.Themethodsyoumentioned(FindByNameAsync,FindByIdAsync,FindByEmailAsync,andFindByLoginAsync)areusedtofindauserbasedondifferentcriteria.T......
  • 性能测试-基础篇
    前言:性能是什么 每个人眼里对性能理解不一样,但是我们如果从一个App的维度来看: 用户眼中的性能:1、App使用崩溃,卡顿,延迟2、App反应慢,使用页面无反应 那开发眼中的性能:1、数据库设计是否合理2、代码逻辑、算法是否可以优化 运维眼中的性能:1、服务器资源使用是否合理......
  • Replace bpmn-js and Let Frontend Developers Become More Familiar with Workflow B
    (背景:发在国外社区的文章,国内博客做份存档)PrefaceSeeingthistitle,someofyoumaywonder:Isn'tbpmn-jsthemostcommonfrontendsolutionforworkflowsystems?Whydoweneedtoreplacebpmn-js?Here,fromafrontendperspective,let'sfirstclarifytherel......
  • Java Web Service Get请求使用指南
    JavaWebServiceGet请求使用指南在当今互联网时代,WebService已经成为了现代软件开发中不可或缺的一部分。而Java作为一种广泛使用的编程语言,自然也提供了丰富的工具和库来支持WebService的开发。本文将为大家介绍如何使用Java编程语言进行WebService的Get请求。JavaWebserv......
  • Photoshop 2023 for mac(ps 2023 ai beta)v25.0beta中文版
    Photoshop 2023mac更新了,智能AI在ps 2023beta版上线了。ps2023更新内容有内置AI绘图、有实时渐变、生成填充等功能,还支持神经滤镜,帮你打造更加强大的创作。ps2023mac中文版系统要求•需要macOS11或更高版本•Intel或AppleSilicon•8GBRAM(推荐16GB)•4GB可用硬......
  • 通过vcenter提取主机配置文件方式修改esxi root密码
    1,登陆vcenter2,右击任意一台主机-->主机配置文件-->提取主机配置文件3,为新的主机配置命名,如change-passwd4,选择vcenter管理菜单-->策略与配置文件,修改主机配置文件5,编辑主机配置文件-->编辑-->搜索root-->去掉其它选项-->在密码类型中选择固定的密码配置-->保存(这一步要一定小心,不......
  • 支持多数据源联合查询的SQL运行引擎sycnany-SQL添加使用自定义函数
    在微服务和云原生愈发流行的今天,数据的分布也愈发脱离单库单机而更加复杂,使用的数据库类型也会更多,但业务的复杂依然会带来了大量的数据查询和导出需求,而很多时候我们很难为数据量的大部分系统创建完整的BI数仓系统,这时候你是不是觉得为这些需求查询和导出数据就会是一个十分困难且......
  • centos系统给usb网卡设置静态ip
    centos系统usb网卡设置静态ip有一台普通电脑作为服务器,装centos系统,没有图形界面。因为主板自带的网卡坏了(重新装过的系统发现/etc/sysconfig/network-scripts目录下没有ifcfg-eth0或者ifcfg-ens33这种类似的网络文件),所以用了绿联的usb转网卡插在主机的usb用,插上去后发现是可以自动......
  • 【230807-3】在三角形ABC中,内角A,B,C所对的边分别是a,b,c,且2aSinA=(2SinB+SinC)b+(2c
    ......
  • 【230807-1】在三角形ABC中,内角A,B,C所对的边分别是a,b,c,若a^2=3b^2+3c^2-2bcSinA*根
    ......