代码改变世界

【值类型VS引用类型】 And【值传递VS引用传递】

2012-08-10 23:22  Max蚊子  阅读(966)  评论(7编辑  收藏  举报

      以前知道值分为值类型、引用类型,参数传递的时候分为值传递、引用传递,各种书里面、论坛、园里面都有各种解释,但是有些地方是一带而过,没有说很具体。下面就我个人理解说说,以前总是认为他们是有关系的,现在个人理解的是【值类型VS引用类型】 与【值传递VS引用传递】完全没得关系八竿子打不着的事儿。有不同意见的可以大家一起讨论

     1、首先说说【值类型VS引用类型】:

      值类型(形如:int、bool、struct等等)就是存储在堆栈(其实就是线程栈,基本就是用完了就被操作系统回收了),如上图值类型直接存储了值:A的值为5

                 引用类型(class 修饰的)是存储在托管堆的是GC来判定是否回收,如上图,堆栈里面其实就是存储的是一个托管堆的地址,当访问的时候会先找到01xx04这个地址,然后发现时引用类型并且指向托管堆地址为0Exx03,然后就可以访问对象中的x=1,y=2的值了。明显看出引用类型比值类型多了一道关卡,所以引用类型要慢一拍。

 

    PS:再次强调【值类型VS引用类型】 与【值传递VS引用传递】其实是完全没有关系的

    2、 然后就说说【值传递VS引用传递】:

    简单点说吧,用ref 和out修饰参数的才是引用传递,其他都是值传递。

    【值传递】:用值传递的时候形参会再次分配内存空间02xx02、02xx04,传递的值就是 5和0Exx03,所以形参接收过来就是a=5了,对象在堆栈中存储的就是0Exx03地址指向托管堆

    【引用传递】:用引用传递的时候形参再次分配内存空间02xx02存储的01xx02,而02xx04存储地址01xx04,所以修改之后直接影响到了实参结果:x值变为了10000,而aClass指向了新的对象。(注意:有些人认为引用传时,ChangeRef 这里面的aClass不会影响Page_Load中的aClass,但事实是影响了。)

实验代码如下:

  

    protected void Page_Load(object sender, EventArgs e)
    {
        int age;
        int iResult;

        int x=888;
        A aClass = new A(10);

        ChangeValue(x, aClass);
        age = aClass.Age;//2012
        iResult = x;//888

        ChangeRef(ref x, ref aClass);

        age = aClass.Age;//10000
        iResult = x;//10000



        int i = 0;

    }

    public void ChangeRef(ref int i,  ref A aClass)
    {
        i = 10000;
        aClass = new A(10000);//这儿重新指向了一个对象,实参也指向了这个新的对象
    }
    public void ChangeValue(int i, A aClass)
    {
        i = 2012;
        aClass.Age = 2012;
    }
}


public class A
{
   public int Age;
   public A(int value) { Age = value; }
}

 

 

 

    以上纯属个人理解,完全是抛砖引玉,希望大家多多指点。

      

网站:feiger.cn         飞鸽博客,关注互联网、站长圈的程序员博客!