引用类型和值类型学习笔记
一、基本概念
CLR支持两种类型,值类型和引用类型。它们从类型的定义、实例的创建、参数传递、到内存的分配都有所不同;.NET中的类型分类如下:
值类型和引用类型最本质的区别在于内存的分布上,大致可以这么说---->:值类型存在栈上,引用类型存在堆上;
1、什么是堆和栈?
栈(stack):栈是基于线程的,一个线程会包含一个线程栈。线程中的值类型在对象作用域结束的时候会自动被清理;栈是由操作系统负责管理的,用于存放值类型变量和引用类型在托管堆上的地址;
托管堆(GC Heap):进程在初始化的时候在进程地址空间上划分内存,存储.NET运行过程中的对象,所有的引用类型都存储在托管堆上,托管堆上分配的对象是由GC负责管理和释放的;托管堆是基于进程的;
二、值类型一直都存在栈上吗,引用类型一直都存在堆上吗?
1.单独的值类型变量,如局部值类型变量都是存储在栈上面的;
2.当值类型是自定义class的一个字段、属性时,它随引用类型存储在托管堆上,此时她是引用类型的一部分;
4.所有的引用类型肯定都是存放在托管堆上的。
5.结构体(值类型)中定义引用类型字段,结构体是存储在栈上,其引用变量字段只存储内存地址,指向堆中的引用实例。
三、值类型和引用类型的参数传递
值类型变量在传递给另外一个变量时,会执行一次复制,复制的是值;
引用类型在传递给另一个变量时,也会执行一次复制,但复制的却是引用对象的地址;
int v1 = 0;int v2 = v1;v2 = 100;Console.WriteLine("v1=" + v1); //输出:v1=0Console.WriteLine("v2=" + v2); //输出:v2=100 User u1=new User();u1.Age = 0;User u2 = u1;u2.Age = 100;Console.WriteLine("u1.Age=" + u1.Age); //输出:u1.Age=100Console.WriteLine("u2.Age=" + u2.Age); //输出:u2.Age=100,因为u1/u2指向同一个对象
当把对象作为参数传递的时候,效果同上面一样,他们都称为按值传递;
四、引用传递:
按引用传递的两个主要关键字:out
和 ref
不管值类型还是引用类型,按引用传递的效果是一样的,都不传递值副本,而是引用的引用(类似c++的指针的指针)
out
和 ref
告诉编译器方法传递额是参数地址,而不是参数本身;
private void DoTest( ref int a){a *= 2;}private void DoUserTest(ref User user){user.Age *= 2;}[NUnit.Framework.Test]public void DoParaTest(){int a = 10;DoTest(ref a);Console.WriteLine("a=" + a); //输出:a=20 ,a的值改变了User user = new User();user.Age = 10;DoUserTest(ref user);Console.WriteLine("user.Age=" + user.Age); //输出:user.Age=20}
out
和 ref
的主要异同:
out
和ref
都指示编译器传递参数地址,在行为上是相同的;- 他们的使用机制稍有不同,ref要求参数在使用之前要显式初始化,out要在方法内部初始化;
out
和ref
不可以重载,就是不能定义Method(ref int a)和Method(out int a)这样的重载,从编译角度看,二者的实质是相同的,只是使用时有区别;
摘抄自:http://www.cnblogs.com/anding/p/5229756.html
转载于:https://www.cnblogs.com/DuoLaCM/p/5243755.html
引用类型和值类型学习笔记相关推荐
- 读书笔记_CLR.via.c#第五章_基元类型_引用类型_值类型
基元类型 1.不管在什么操作系统上c#的int始终代表32位整数. 2.c#中long代表64位. 类型转换 安全转换时,才允许隐式转型. 不安全转换时,为显式转型. 溢出检测方法 控制溢出的一个办法 ...
- 第五章 基元类型、引用类型、值类型 CLR学习第五课
一.基元类型:编译器直接支持的数据类型称为基元类型(如int类型其对于的是system.int32). 二.类型溢出,可以用checked 和unchecked进行类型溢出检查和不进行类型溢出检查.一 ...
- 《CLR via C#》读书笔记 之 基元类型、引用类型和值类型
第五章 基元类型.引用类型和值类型 2013-02-27 5.3 值类型的装箱和拆箱 5.3.2 对象的相等性和同一性 参考 ToDo: 什么时候使用值类型,什么时候使用引用类型 5.3 值类 ...
- 《C++Primer》第二章-变量和基本类型-学习笔记(1)
<C++Primer>第二章-变量和基本类型-学习笔记(1) 文章目录 <C++Primer>第二章-变量和基本类型-学习笔记(1) 摘要 主体 基本(内置)类型 算数类型 整 ...
- 内置对象的API Array数组对象 String字符串对象 json字符串 JSON对象 js作用域及变量预解析 引用类型与值类型区别 共享引用 基本包装类型 数组去重
01-内置对象的API a.Date对象获取时间 b.Array对象数组加工 c.String对象字符串加工 d.json字符串的语法格式 e.JSON对象的字符串与对象转换应用 02-JS作用域 a ...
- 跟小静读CLR via C#(02)-基元类型、引用类型、值类型
跟小静读CLR via C#(02)-基元类型.引用类型.值类型 一. 基元类型 编译器能够直接支持的数据类型叫做基元类型.例如int, string等.基元类型和.NET框架类库FCL存在着直接的映 ...
- .NET引用类型与值类型
值类型和引用类型的基类 引用类型和值类型都继承自System.Object类.不同的是,几乎所有的引用类型都直接从System.Object继承,而值类型则继承其子类,即直接继承System.Valu ...
- [转载]实际举例C#引用类型和值类型的区别
http://www.cnblogs.com/coolbeibei/archive/2009/03/23/1419706.html 实际举例C#引用类型和值类型的区别 我们都知道,c#的两大数据类型分 ...
- .net 基元类型,引用类型和值类型
基元类型(primitive type): 编译器直接支持的数据类型称为基元类型(primitive type). string 与 String: 由于C#中的string (一个关键字)直接映射到 ...
最新文章
- java好还是python好-Python和Java该如何选择?选哪个好?
- 开放域知识库问答研究回顾
- 使用RDLC报表(二)--使用自定义数据集
- 软件工程--第五章-- 总体设计
- python列表批量 修改_python实现多进程按序号批量修改文件名的方法示例
- 【渝粤教育】国家开放大学2019年春季 1308外国文学专题 参考试题
- 100c之23:两个平方数
- C语言fscanf和fprintf函数的用法详解
- Android 内存泄漏之handler
- Jenkins配置MSBuild时使用环境变量
- 「leetcode」203.移除链表元素:听说用虚拟头节点会方便很多?
- 【回归预测】基于matlab离群鲁棒极限学习机(ORELM)求解回归预测问题【含Matlab源码 1441期】
- 原生ajax方法,原生Ajax怎么写
- 激光打标机二次开发C#实例分享(附带实例源码)
- 脚本之家电子书下载:https://www.jb51.net/books/
- 数据库mysql实训报告_数据库实训报告.doc
- 【icem】非结构体网格的质量+混合网格的合并问题
- mysql5.1.40.jrp_1.原生态JDBC编程中的问题总结
- 电脑公司特供版 GHOSTXPSP3_2013新春特别版
- 8.Python中装饰器是什么?
热门文章
- SpringMVC3 AnnotationMethodHandlerAdapter与mvc:annotation-driven冲突的解决方案
- ECSHOP模板设置只有登录用户才能查看商品详情内容
- android 巧用动画使您app风骚起来
- 【笔记】《C#高效编程改进C#代码的50个行之有效的办法》第1章C#语言习惯(1)--属性的特性以及索引器(SamWang)...
- 在Windows Server 2003上运行vSphere Client 4.0出现“clients.xml文件出错r
- Python 代码覆盖率统计工具 coverage.py
- Linux中shell编程的for循环用法
- Linux下发生段错误时如何产生core文件-转
- linux egrep和grep区别,linux中grep和fgrep有什么区别
- 智能擦窗机器人的社会意义_告别传统清扫方式 AWE玻妞展示擦窗机器人