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#学习笔记(基础知识回顾)之值类型和引用类型 二:给方法传递参数分为值传递和引用传递. 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.分布式事务.高并发 ...
随机推荐
- 认识ASP.NET MVC6
认识ASP.NET MVC6 这篇文章说明下如何在普通编辑器下面开发mvc6应用程序. 上篇文章: 十分钟轻松让你认识ASP.NET 5(MVC6) 首先安装mvc6的nuget包: 可以看到在pro ...
- Pku1218
<span style="background-color: rgb(204, 204, 204);">/* A - THE DRUNK JAILER Time Lim ...
- 一个大浪Java罢工(一个)安装JDK和环境变量配置
一个.基础知识 (一)什么是Java? Java是一种能够撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台( ...
- HDU 3094 A tree game 树删边游戏
叶节点SG值至0 非叶节点SG值至于它的所有子节点SG值添加1 XOR和后 #include <cstdio> #include <cstring> #include < ...
- Linux C语言操作MySQL
原文:Linux C语言操作MySQL 1.MySQL数据库简介 MySQL是一个开源码的小型关系数据库管理系统,体积小,速度快,总体成本低,开源.MySQL有以下特性: (1) 使用C和C++编写, ...
- u-boot学习(两):u-boot简要分析
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 看到不错的文章.不要加入收藏夹, ...
- 快速构建Windows 8风格应用22-MessageDialog
原文:快速构建Windows 8风格应用22-MessageDialog 本篇博文主要介绍MessageDialog概述.MessageDialog常用属性和方法.如何构建MessageDialog ...
- 图解IntelliJ IDEA 13版本对Android SQLite数据库的支持
IntelliJ IDEA 13版本的重要构建之一是支持Android程序开发.当然对Android SQLite数据库的支持也就成为了Android开发者对IntelliJ IDEA 13版本的绝对 ...
- [译]在运行时内存中的Java对象是怎么样的
(文章翻译自What do Java objects look like in memory during run-time?) 我们知道函数在内存中是作为一个活动记录栈来实现的.而且我们知道Java ...
- javascript模拟title提示效果
本代码可以实现如下情况: 1.js实现title是为了解决自定义样式和格式! 2.希望传入的格式可以不限制是否包含html结构! 3.可以自定义显示层的位置! js如下: function GetAb ...