zoukankan      html  css  js  c++  java
  • C#基础原理拾遗——引用类型的值传递和引用传递

    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,即引用传递的话:

    捕获1

    变量xiaohong和student指向同一栈地址,在student = new Student(…)后,该栈001指向新的堆地址10010,而xiaohong也指向001栈。所以方法调用后xiaohong指向的对象变成了“红姐”18。

          至此,我总结出:值传递是传递栈中的值;引用传递是传递栈地址。

          这一次我是蛮认真的写的这篇博客,希望人气能好一点,不吝留言赐教的话就感激不尽了。

  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3173840.html
Copyright © 2011-2022 走看看