zoukankan      html  css  js  c++  java
  • 只说ref

         先贴一段代码:

    class Program
    {
    static void Main(string[] args)
    {
    string ss = "asdf";
    operate(ss);
    Console.WriteLine(ss);
    Console.Read();
    }
    public static void operate(string aa)
    {
    aa = "sdf";
    Console.WriteLine(aa);
    }
    }


    输出是:

     sdf

    asdf

          先解释这个东西,在.net中值类型是存放在堆栈中的,引用类型分为两部分存储,一部分是指针存储在堆栈中,另外一部分是类型的实例存储的堆中.

          然后在说下

    string ss = "asdf";

          这一句代码发生了什么,首先.net在栈中分配了一个string类型的指针所需要的地址,它没有指向任何东西.然后.net在堆中查找有没有"asdf"这个string的实例,如果没有它就要新建立一个string实例为asdf然后把此实例的地址赋给刚才在栈中分配的那个指针,这就是等号的作用.

          然后我们在看operate(ss);这一句代码发生了什么.这个地方传递过来的是堆里面asdf的地址,然后.net又在栈上分配了一个string类型的指针所需要的地址,这一块地址就叫aa,但是呢这个aa中是有值的它的值就是刚才我们给asdf分配在堆上的内存区域的值.

          接着 aa = "sdf";由于已经给aa在栈上分配了内存区域,所以直接在堆上找有没有sdf这个实例,没有! 好重新拿出一块来存放sdf,然后把这块的内存地址放到刚才给aa分配的地址里面.

    后面的两个输出就简单了,只要分别输出栈里指针所指向的堆里面的值就可以了.

    以上是没有加ref的过程.

          另外一段代码:

     class Program
    {
    static void Main(string[] args)
    {
    string ss = "asdf";
    operate(ref ss);
    Console.WriteLine(ss);
    Console.Read();
    }
    public static void operate(ref string aa)
    {
    aa = "sdf";
    Console.WriteLine(aa);
    }
    }

    输出两行 sdf

          第一句赋值语句不解释了,跟第一种一样.现在来看第二句operate(ref ss);

          多了一个ref那传递过来的东西就不一样了,这里传递过来的是ss所在内存的地址,然后aa = "sdf";的时候还是要在堆上找有没有sdf这个实例,没有的话重新创建,分配堆地址.

    这个地方就是不一样的了,.net将这个分配好的地址编号,赋值给了ss所在的栈地址,而没有将此地址赋值给aa所在的栈地址.所以我们从方法返回后ss所指向的堆地址改变了.所以它的值也改变了

         

  • 相关阅读:
    Python 模块 itertools
    Python 字符串的encode与decode
    python 模块 hashlib(提供多个不同的加密算法)
    暴力尝试安卓gesture.key
    hdu 1300 Pearls(DP)
    hdu 1232 畅通工程(并查集)
    hdu 1856 More is better(并查集)
    hdu 1198 Farm Irrigation(并查集)
    hdu 3635 Dragon Balls(并查集)
    hdu 3038 How Many Answers Are Wrong(并查集)
  • 原文地址:https://www.cnblogs.com/glorysword/p/2314988.html
Copyright © 2011-2022 走看看