解决方案 »

  1.   

    (我的问题是:s2是指向abc的, 而s=s.ToLower();后 s同样也指向的是abc)我想不通的是为什么输出的是false。而下面的那段代码ReferenceEquals(a, b)却是输出true。
      

  2.   

    Console.WriteLine(ReferenceEquals(s, s2));  //输出false  (我的问题是:s2是指向abc的, 而s=s.ToLower();后 s同样也指向的是abc)我想不通的是为什么输出的是false。而下面的那段代码ReferenceEquals(a, b)却是输出true。   恳请各位指定迷津。谢谢。
      

  3.   

    本帖最后由 bdmh 于 2014-02-24 16:22:05 编辑
      

  4.   

    就像new2个对象,赋相同的值,内容虽然相同,但肯定不是同一个引用。最后一个是常量优化,编译期间发现相同的常量只会有一个,就是同一个引用了。
      

  5.   

    当把一个字符串常量放入堆栈时,.net做了优化,它会直接复用已经初始化的字符串。但是一旦你实际算出来的,例如通过 ToLower 计算出来的,那么就不存在这个优化了。
      

  6.   

    字符串的值是不能修改的。
    当你用s=s.ToUpper()后,“abc"依然保持不变,而是新开辟一块内存用来存放"ABC",并且让s指向"ABC".而原来的s2依然指向"abc"所在的内存。所以两个变量指向的是内存中不同的地址。所以返回false.最后的代码中为什么返回true?
    这是因为.net 的字符串池的机制,为了提高效率,.net采用这样一种机制。因为你第一次赋值变量为"abcd"时,这个字符串已经放到了内存池中,接着第二个变量又赋值为"abcd",这时会直接让第二个变量指向这个已经存在的字符串,而不是去重新创建一个新的字符串,采用这种方法就提高了效率。
      

  7.   


     问题是当我再次s=s.ToLower();的时候 此时的s="abc" 。 而之前内存中已经创建了一个"abc",用s2来指向它的。 按照.NET的优化机制,s=s.ToLower()的时候应该是让s再次指向s2所指向的"abc"才对啊。
      

  8.   


    没有这个优化机制。.net没有你想象的那样肯花很多时间去做貌似智能的东西。只有在初始化装载字符串常量的时候(这恰好对应MSIL预设的唯一条汇编代码)才能优化,而计算出来的不能优化。
      

  9.   


     问题是当我再次s=s.ToLower();的时候 此时的s="abc" 。 而之前内存中已经创建了一个"abc",用s2来指向它的。 按照.NET的优化机制,s=s.ToLower()的时候应该是让s再次指向s2所指向的"abc"才对啊。
    我没有把字符串池讲得很详细,你可以参考10楼的回复,另外去网上或书上看一下这个优化机制。
      

  10.   


     问题是当我再次s=s.ToLower();的时候 此时的s="abc" 。 而之前内存中已经创建了一个"abc",用s2来指向它的。 按照.NET的优化机制,s=s.ToLower()的时候应该是让s再次指向s2所指向的"abc"才对啊。
    我没有把字符串池讲得很详细,你可以参考10楼的回复,另外去网上或书上看一下这个优化机制。谢谢你的详细解答,辛苦了您了,非常感谢。
      

  11.   

    基本是 Copy-On-Write ( COW )(写时复制)
      

  12.   


    没有这个优化机制。.net没有你想象的那样肯花很多时间去做貌似智能的东西。只有在初始化装载字符串常量的时候(这恰好对应MSIL预设的唯一条汇编代码)才能优化,而计算出来的不能优化。谢谢。明白了。