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#基础原理拾遗——引用类型的值传递和引用传递的更多相关文章

  1. C#基础原理拾遗——引用类型的值传递和引用传递

    以前写博客不深动,只搭个架子,像做笔记,没有自己的思考,也没什么人来看.这个毛病得改,就从这一篇开始- 最近准备面试,深感基础之重要,奈何我不是计算机科班出身,基础方面有些捉襟见肘.短期怎么补?做面实 ...

  2. C#学习笔记(基础知识回顾)之值传递和引用传递

    一:要了解值传递和引用传递,先要知道这两种类型含义,可以参考上一篇 C#学习笔记(基础知识回顾)之值类型和引用类型 二:给方法传递参数分为值传递和引用传递. 2.1在变量通过引用传递给方法时,被调用的 ...

  3. java基础 - 形参和实参,值传递和引用传递

    形参和实参 形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的. 形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元. 因此,形 ...

  4. GO语言基础---值传递与引用传递

    package main import ( "fmt" ) /* 值传递 函数的[形式参数]是对[实际参数]的值拷贝 所有对地址中内容的修改都与外界的实际参数无关 所有基本数据类型 ...

  5. 堆栈详解 + 彻底理解Java的值传递和引用传递

    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...

  6. 一个随意list引发的惨案(java到底是值传递还是引用 传递?)

    前两天写了一个递归,因为太年轻,把一个递归方法需要用到的list定义该递归方法外了,结果开始断点测试的时候有点小问题 ,然后上线之后因为数据量太多导致了一个java.util.ConcurrentMo ...

  7. Java的值传递和引用传递的说法

    学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java ...

  8. Java 值传递 or 引用传递?

    Java 方法传参 值传递 or 引用传递? 结论:Java采用的是值传递 先建立一些基础的概念 什么是值传递和引用传递? 值传递(pass by value):是指在调用函数时将实际参数复制一份传递 ...

  9. 死磕面试系列,Java到底是值传递还是引用传递?

    Java到底是值传递还是引用传递? 这虽然是一个老生常谈的问题,但是对于没有深入研究过这块,或者Java基础不牢的同学,还是很难回答得让人满意. 可能很多同学能够很轻松的背出JVM.分布式事务.高并发 ...

随机推荐

  1. Yii Framework2.0开发教程(10)配合mysql数据库实现用户登录

    1.首先在mysql创建一个存用户的表格 create table test_user ( user_id bigint(20) unsigned not null auto_increment co ...

  2. 【Unity 3D】学习笔记四十一:关节

    关节 关节组件能够加入至多个游戏对象中,而加入关节的游戏对象将通过关节连接在一起而且感觉连带的物理效果.须要注意的是:关节必须依赖于刚体组件. 关节介绍 关节一共分为5大类:链条关节,固定关节,弹簧关 ...

  3. GhostDoc的使用

    原文:GhostDoc的使用 一.简介 GhostDoc是Visual Studio的一个免费插件,可以为开发人员自动生成XML格式的注释文档. 二.下载 需要的朋友可以去这里下载,填个Email地址 ...

  4. Asp.Net MVC4 + Oracle + EasyUI + Bootstrap 1

    Asp.Net MVC4 + Oracle + EasyUI + Bootstrap 序章 Asp.Net MVC4 + Oracle + EasyUI + Bootstrap 序章 -- 新建微软实 ...

  5. 快速构建Windows 8风格应用10-设备方向

    原文:快速构建Windows 8风格应用10-设备方向 本篇博文主要介绍常用支持Windows 8操作系统设备的方向.如何获取当前设备方向.DisplayProperties类. 常用支持Window ...

  6. 一个只能用在Win下的密码验证函数(显示星号,可删除)

    以前做小程序时图好玩在网上找的代码.输入的密码会以星号显示出来,并且输入错了可以删除.因为用了专有库函数,所以只能在Windows平台使用,少用为好,不过可能还有点用.嗯…就这样了 #include ...

  7. Error with mysqld_safe

    出处:http://bugs.mysql.com/bug.php?id=18403 Description: - I downloaded the binary file “Standard 5.0. ...

  8. C#中IList<T>与List<T>的区别

    首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口.它仅仅是所有泛型类型的接口,并没有太多方法可以方便实用,如果仅仅是作为集合数据的承载体,确实,IList ...

  9. SSMS2008插件开发(1)--介绍

    原文:SSMS2008插件开发(1)--介绍 SSMS2008就是Microsoft Sql Server Management Studio 2008的简称.许多人叫做SQL2008或SQL SER ...

  10. 【转】Android的Merge讲解与实例

    原文:http://blog.sina.com.cn/s/blog_62f987620100sf13.html 单独将<merge />标签做个介绍,是因为它在优化UI结构时起到很重要的作 ...