频道栏目
首页 > 资讯 > C# > 正文

.Net Framework: 字符串的驻留(String Interning)

10-07-11        来源:[db:作者]  
收藏   我要投稿

关于字符串的驻留的机制,对于那些了解它的人肯定会认为很简单,但是我相信会有很大一部分人对它存在迷惑。在开始关于字符串的驻留之前,先给出一个有趣的Sample: 
   
  Code Snip: 
  
  static void Main(string[] args) 
   { 
   string str1 = "ABCD1234"; 
   string str2 = "ABCD1234"; 
   string str3 = "ABCD"; 
   string str4 = "1234"; 
   string str5 = "ABCD" + "1234"; 
   string str6 = "ABCD" + str4; 
   string str7 = str3 + str4; 
   
   Console.WriteLine("string str1 = "ABCD1234";"); 
   Console.WriteLine("string str2 = "ABCD1234";"); 
   Console.WriteLine("string str3 = "ABCD";"); 
   Console.WriteLine("string str4 = "1234";"); 
   Console.WriteLine("string str5 = "ABCD" + "1234";"); 
   Console.WriteLine("string str6 = "ABCD" + str4;"); 
   Console.WriteLine("string str7 = str3 + str4;"); 
   
   Console.WriteLine(" object.ReferenceEquals(str1, str2) = {0}", object.ReferenceEquals(str1, str2)); 
   Console.WriteLine("object.ReferenceEquals(str1, "ABCD1234") = {0}", object.ReferenceEquals(str1, "ABCD1234")); 
   
   Console.WriteLine(" object.ReferenceEquals(str1, str5) = {0}", object.ReferenceEquals(str1, str5)); 
   Console.WriteLine("object.ReferenceEquals(str1, str6) = {0}", object.ReferenceEquals(str1, str6)); 
   Console.WriteLine("object.ReferenceEquals(str1, str7) = {0}", object.ReferenceEquals(str1, str7)); 
   
   Console.WriteLine(" object.ReferenceEquals(str1, string.Intern(str6)) = {0}", object.ReferenceEquals(str1, string.Intern(str6))); 
   Console.WriteLine("object.ReferenceEquals(str1, string.Intern(str7)) = {0}", object.ReferenceEquals(str1, string.Intern(str7))); 
   } 
   
   
  下边是输出的结果: 
   
  接下来我们来逐句地分析这段代码: 
   
  首先我们创建了两个完全相同的字符串(ABCD1234),并将他们分别赋予了两个字符创变量——str1和str2。然后把它们传给了object.ReferenceEquals。我们知道object.ReferenceEquals是用于确定两个变量是否具有相同的引用——换句话说,当两个变量引用的是同一块托管推的内存快的时候,返回True,否则返回False。 
   
  string str1 = "ABCD1234"; 
  string str2 = "ABCD1234"; 
  object.ReferenceEquals(str1, str2)= True; 
  object.ReferenceEquals(str1, "ABCD1234")) = True; 
   
  令我们感到奇怪的是,当我们分别创建的引用类型两个变量——string是引用类型。照理说CLR会在托管堆(Managed Heap)中为它们分配两段内存快,他们不可能具有相同的引用才对,但是为什么object.ReferenceEquals 方法会返回True呢。而对于第二个比较——一个字符串变量和一个和他具有相同内容的字符串("ABCD1234";)直接进行比较,按照我们对CLR内存的分配的一般理解,应该是CLR首先会在托管堆中为这段字符串("ABCD1234")分配内存快,然后把相对应的引用传递给object.ReferenceEquals方法(由于分配在托管堆的这段字符串并没有被任何变量引用,所以当垃圾回收的时候会被回收掉),所以无论如何也不应该返回True。 
   
  我们先把问题留到最后,接着分析我们的Sample。上面们对字符串变量之间以及变量与字符串之间进行了比较,如果我们对一个字符串变量和一个动态创建的字符串(通过+Operator把两个字符串连接起来)进行比较,结果又会如何呢?我们来看看下面的伪代码演示: 
   
  string str3 = "ABCD"; 
  string str4 = "1234"; 
  string str5 = "ABCD" + "1234"; 
  string str6 = "ABCD" + str4; 
  string str7 = str3 + str4; 
  object.ReferenceEquals(str1, str5) = True 
  object.ReferenceEquals(str1, str6) = False 
  object.ReferenceEquals(str1, str7)) = False 
   
  在上面的例子中,我们用三种不同的方式创建了3个字符串变量(str5,str6,str7)——string+string;string+variable;variable+variable。然后分别和我们已经创建的、和它们具有相同字符串“值”的变量(str1)作比较。同样令我们感到奇怪的是第一个返回True,而后两个则为False。带着这些疑惑我们来看看对于string这一特殊的类型说采用的特殊的

相关TAG标签
上一篇:栈及其在.NET FrameWork中的源码分析
下一篇:把c#中的Array说透
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站