关于string的一个问题

请参见这篇文章 “Re: 关于string的一个问题

C#中的string类型比较特殊
  1) 它是Immutable的,即不可改变的(虽然也有别的方法可以改变,可参见也说C#中的Immutable)。
  2) 它重载了运算符“==” ,实现了str1 == str2的值比较,而不是引用的比较。
  3) 它本身却又是引用类型。

今天遇到一个问题。先看代码
Code

结果是什么? True or false?

大家都知道,.net的引用类型,其实每一个实例都是一个类的引用,在堆上分配不同的地址。因此,比如 ClassA instance1 = new ClassA(); ClassA instance2 = new ClassA(); 其实指向的是两个不同的内存地址。因此,object.ReferenceEquals(instance1, instance2)返回的应该是false。

但是,上面代码却返回的True。有点抽象。既然是True,就证明它引用的是同一个对象。那么,指向的内存地址应该是一样的了。好,为了证明以上推论,我写了下面的代码
Verify two string instance reference the same address

结果跟预料的一样,返回的是True。

我在网上找到这么一段话:
“In C# strings are reference types. However, operator==() is overloaded for strings and compares string contents, not reference equality. String.Equals() also compares string contents. What makes strings unique is that string literals are pooled. For instance, if we have the following code:

string s1 = "abc";
string s2 = "abc";
bool result = Object.ReferenceEquals(s1,s2);

the value of result will be true. ReferenceEquals() is not lying here. s1 and s2 indeed reference the same object. The sysetm recognized that we have two equivalent string literals, and merged them into one. It can get away with it, because string objects are immutable. This check for duplicate string literals occurs when you code is JIT-compiled, i.e. converted from IL (intermediate language) to native (x86) machine codes. Thus, string literals are merged even when they are from different assemblies.Note, however, that merging process affects only string literals”。

也就是说,系统把两个string 对象合并成一个了。

这样的好处,我想可能是避免在代码中给string 对象赋予相同值得时候,在heap上重复创建对象(尤其在循环中)所造成的性能损失吧。
posted @ 2009-10-12 16:46  麦穗  阅读(297)  评论(2编辑  收藏  举报