关于string中涉及到的暂存池

关于string中涉及到的暂存池

之前看了一些string相关的博客,感觉写的挺好,但终究还是没深究。哎,学习最怕就是我这种心态了吧!

今天看了一些C#相关的面试题,其中一题感觉很简单,题目如下:

string a = "abc";
a = (a.ToUpper()+"123").SubString(0,2);

问上述代码运行时总共会产生多少个临时对象?

自己看了下,应该是5个:
ToUpper()会产生一个”ABC”,“123”算一个,“ABC”+”123”=”ABC123”又是一个,SubString()也会产生一个(“AB”),再加上a本身的那个,总共是5个。
但是自己想了想,应该如何验证自己的想法呢?避免出现模棱两可的情况。所以打算亲自验证下,但是验证也无法实际验证,因为这些都是临时变量,它们并没有一个变量来存储,所以用调试的方式来验证也是不太可行的。
无奈,只能将上面的代码改成如下:

        static void Main()
        {
            string a = "abc";
            string b = a.ToUpper();
            string c = "123";
            string d = b + c;
            string e = d.Substring(0, 2);
            string f = "AB";
        }

然后用调试的方法来查看各个字符串变量的内存地址。
本以为应该会很快解决这个问题,但调试了一遍之后发现不对劲!记得之前看的string相关的博客里提到过,两个完全相同的字符串(string对象),他们在C#中引用的会是同一块内存地址。但上面的调试结果却让我傻眼了。变量e和f的值是一样的,但是它们的地址却不一样!这是为何?

后来又看了下之前的那篇文章:《你真的了解.NET中的String吗?》,发现这篇文章中其实也提到了我遇到的问题,只是没有明确说明。这对于还是小白的我来说,由于不了解C#中String类的暂存池机制,所以之前也是略知一二,知道相同字符串引用的是同一块内存,但却忽略了一个严重的前提!这个字符串前提是必须在暂存池当中。
而查到这个暂存池主要是因为看到了String.Intern(string)这个静态方法。查了下,正好查到了要找的内容:
《囧,对C#驻留池(Intern Pool)机制的误解》
这里简单讲解了暂存池,也就是驻留池的一些机制:

  • 驻留池由CLR来维护,其中的所有字符串对象的值都不相同
    驻留池中的所有字符串都不一样,以此来保证相同字符串的引用地址是相同的。

  • 只有编译阶段的文本字符常量会被自动添加到驻留池,运行时期动态创建的字符串不会被加入到驻留池中
    这也就是为什么我上面调试的时候发现e和f的地址不一样的原因了。这里也很好理解,因为f的值在编译阶段就已经确定了的,是静态的文字常量,而e的值是经过运行产生的,所以e的值不会被存放到Intern Pool中。

  • 可以使用静态方法String.Intern(string)把动态创建的字符串加入到驻留池中
    要使e和f的引用相同,使用这个方法即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值