C#基础原理拾遗——引用类型的值传递和引用传递
以前写博客不深动,只搭个架子,像做笔记,没有自己的思考,也没什么人来看。这个毛病得改,就从这一篇开始…
最近准备面试,深感基础之重要,奈何我不是计算机科班出身,基础方面有些捉襟见肘。短期怎么补?做面实题呗。遇到哪儿没理解透,自己查资料,印象深刻。这个问题就是这么来的。原题很简单:“对于方法,参数传递分为值传递和____两种。”这还不简单,但我得拓展啊,得思考啊…
以下1、2是我的意淫,但记录自己的一些错误想法并思考改正还是有益处的,希望不会对大家有误导。觉得麻烦的话可以直接看3。
1、什么是值传递和引用传递?
我一开始的理解是,值类型根本没有引用啊,它能有引用传递?它的值传递和引用传递应该是一样的。至于引用类型,它的值传递应该是一个深拷贝,引用传递应该是一个浅拷贝。对于这一类比,最初还颇感得意。但查资料才知道,What a stupid idea!没办法,非科班出身,知识不成体系,有盲点,但我知道这不是借口,这不在大补嘛,补得跟小鸡子似的。
看了http://www.cnblogs.com/whc-blog/archive/2011/07/20/2111803.html这篇,感性的知道了什么是值传递和引用传递。其实也不是压根不知道,长时间不用忘了,然后就出现了上面离奇的想法。
其实在整个思考完了以后我给值传递和引用传递下了个定义,在这里先搬出来:(欢迎大家批评指正)
值传递是传递栈中的值;引用传递是传递栈地址。
2、引用类型的值传递和引用传递可以类比成深拷贝和浅拷贝吗?
到此对于这个问题还是有疑问的,就写了个小Demo
class Program
{
static void Main(string[] args)
{
Student xiaohong = new Student("小红", 12);
BanZheng(ref xiaohong);
//BanJiaZheng(xiaohong);
Console.WriteLine(xiaohong.Name + " " + xiaohong.Age);
Console.ReadKey();
} //办证
static void BanZheng(ref Student student)
{
student.Name = "红姐";
student.Age = 18;
}
//办假证
static void BanJiaZheng(Student student)
{
student.Name = "红姐";
student.Age = 18;
}
} class Student
{
public Student(string name, int age)
{
Name = name;
Age = age;
}
public string Name { get; set; }
public int Age { get; set; }
}
解释一下:小红今年12,但她要工作,可能家庭困难吧。1、如果她有关系(有关系还家庭困难?解释不了),找到BanZheng方法,给她身份证改成“红姐”18,拿去Main方法输出验证,果然输出“红姐”18。呵呵。但按我理解,ref如果是浅拷贝的话,Age作为一个值类型属性应该是重新烤了一份,其值不应该回传给xiaohong啊,应该输出“红姐”12。看来有关系就是牛逼啊。2、如果她没关系,找了个办假证的BanJiaZheng,一验证还是“红姐”18,如果按我理解,值传递是深拷贝的话,student参数应该和xiaohong是两个完全不同的对象,应该输出“小红”12,看来这个认证机构(我的理解)有水。于是我再查资料…
3、引用类型的值传递和引用传递揭秘
功夫不负有心人,找到这么一篇好文http://www.cnblogs.com/duanwg/archive/2006/07/21/456247.html,其实看了它就能理解了,但我还是根据上面的Demo做些改进,加深理解。
class Program
{
static void Main(string[] args)
{
Student xiaohong = new Student("小红", 12);
BanZheng(ref xiaohong);
//BanJiaZheng(xiaohong);
Console.WriteLine(xiaohong.Name + " " + xiaohong.Age);
Console.ReadKey();
} static void BanZheng(ref Student student)
{
//student.Name = "红姐";
//student.Age = 18; student = new Student("红姐", 18);
} static void BanJiaZheng(Student student)
{
//student.Name = "红姐";
//student.Age = 18; student = new Student("红姐", 18);
}
} class Student
{
public Student(string name, int age)
{
Name = name;
Age = age;
}
public string Name { get; set; }
public int Age { get; set; }
}
这一次办证方法改了,在方法体中student = new Student(…)。再到Main方法中验证一下,如果调用BanZheng方法,输出“红姐”18,如果调用BanJiaZheng方法,输出“小红”12。看来有关系到什么时候都很牛逼啊。
画两个图理解一下:
(1)如果是BanJiaZheng,即值传递的话:
变量xiaohong和student的栈中有相同的堆地址,都指向10000,即“小红”12,而在BanJiaZheng方法中student = new Student(…),开辟了10010堆,student的栈中的堆地址改为10010,而xiaohong的栈中堆地址还是10000。所以方法调用后xiaohong指向的对象没变,依然是“小红”12。
(2)如果是BanZheng,即引用传递的话:
变量xiaohong和student指向同一栈地址,在student = new Student(…)后,该栈001指向新的堆地址10010,而xiaohong也指向001栈。所以方法调用后xiaohong指向的对象变成了“红姐”18。
至此,我总结出:值传递是传递栈中的值;引用传递是传递栈地址。
这一次我是蛮认真的写的这篇博客,希望人气能好一点,不吝留言赐教的话就感激不尽了。
C#基础原理拾遗——引用类型的值传递和引用传递的更多相关文章
- C#基础原理拾遗——引用类型的值传递和引用传递
C#基础原理拾遗——引用类型的值传递和引用传递 以前写博客不深动,只搭个架子,像做笔记,没有自己的思考,也没什么人来看.这个毛病得改,就从这一篇开始… 最近准备面试,深感基础之重要,奈何我不是计算机科 ...
- C#学习笔记(基础知识回顾)之值传递和引用传递
一:要了解值传递和引用传递,先要知道这两种类型含义,可以参考上一篇 C#学习笔记(基础知识回顾)之值类型和引用类型 二:给方法传递参数分为值传递和引用传递. 2.1在变量通过引用传递给方法时,被调用的 ...
- java基础 - 形参和实参,值传递和引用传递
形参和实参 形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的. 形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元. 因此,形 ...
- GO语言基础---值传递与引用传递
package main import ( "fmt" ) /* 值传递 函数的[形式参数]是对[实际参数]的值拷贝 所有对地址中内容的修改都与外界的实际参数无关 所有基本数据类型 ...
- 堆栈详解 + 彻底理解Java的值传递和引用传递
本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...
- 一个随意list引发的惨案(java到底是值传递还是引用 传递?)
前两天写了一个递归,因为太年轻,把一个递归方法需要用到的list定义该递归方法外了,结果开始断点测试的时候有点小问题 ,然后上线之后因为数据量太多导致了一个java.util.ConcurrentMo ...
- Java的值传递和引用传递的说法
学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java ...
- Java 值传递 or 引用传递?
Java 方法传参 值传递 or 引用传递? 结论:Java采用的是值传递 先建立一些基础的概念 什么是值传递和引用传递? 值传递(pass by value):是指在调用函数时将实际参数复制一份传递 ...
- 死磕面试系列,Java到底是值传递还是引用传递?
Java到底是值传递还是引用传递? 这虽然是一个老生常谈的问题,但是对于没有深入研究过这块,或者Java基础不牢的同学,还是很难回答得让人满意. 可能很多同学能够很轻松的背出JVM.分布式事务.高并发 ...
随机推荐
- 采用navicat导出表结构及数据insert声明
旧navicat有一段时间,查找navicat真的很方便,它可以支持各种数据库的. 他一直认为无处不在sql文件比较麻烦,每个表会生成一个sql档,不方便开展进口业务.今天,它已突然发现了一个批次sq ...
- QT 调用 DLL 方法(三种方法)
Qt调用DLL方法一:使用Win32 API 在显式链接下,应用程序必须进行函数 调用以在运行时显式加载 DLL.为显式链接到 DLL,应用程序必须:? 调用 LoadLibrary(或相似的函 数) ...
- Qt 绘制平滑曲线
本文介绍在 Qt 中绘制平滑曲线的实现,调用下面的函数 SmoothCurveGenerator::generateSmoothCurve(points) 即可.默认曲线的 2 个顶点之间被分割为 1 ...
- Java踩坑之路
陆陆续续学Java也快一年多了,从开始的一窍不通到现在的初窥门径,我努力过,迷茫过,痛过,乐过,反思过,沉淀过.趁着新年,我希望能把这些东西记下来,就当是我一路走来的脚印. 一.初识网站应用 记得第一 ...
- WPF“天狗食月”效果
原文:WPF"天狗食月"效果 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/deta ...
- corssplatform---NodeJS基础
什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. 每一种解析器都是一 ...
- youwuku和koudaitong以及weimeng差异
优库通过涨势没有口袋,通过口袋里的东西优库有, 就像一个商场的处理这些极端类别似, 所不同的是:1.掌上通免费,但也开始掏腰包通过用户收费,因为一些特殊的.这意味着,天下没有免费的午餐,掌上通是使用完 ...
- 入骨三分的“我们是谁”IT行业版
这组漫画用简单的台词.粗犷的线条,把很多人心中对甲方(客户)的不满彻底地发泄了一通,并且出现了很多变种版本,引发了传播热潮. http://news.sina.com.cn/c/nd/2017-08- ...
- UVE开发环境搭建及项目启动
1.IDE安装visual studio code ,略: 2.node安装(node-v10.5.0-win-x64.zip),解压即可: 3.配置node环境变量,cmd 输入node -v.np ...
- Xamarin 设置可接受的版本
一共分三个版本,编译版本.最小版本.目标版本(最适应) 一般编译使用最新的版本,目标版本选择最主流的 参考资料 https://docs.microsoft.com/en-us/xamarin/and ...