你真的理解正确String某些特性了吗?

来源:转载

最近在园子里看到几篇关于string的文章,感觉其中有一些误解,不知道是自己理解有误还是园友理解错误,也没发现有园友提出质疑,索性也将自己的一点理解写出来,也对一些质疑提出了自己的解释,不管怎样我希望如果是我哪里理解错误大家一定要提出来,我们一起进步,否则真的会误导很多人,也感觉到写文章是要负责任的,否则就干脆写日志,不要发表出来误导到了一些对.Net不熟悉的朋友!

1.在DoNet中String是不可改变的,什么叫不可变呢,首先大家先看下面的例子:

string a = "1";
Console.WriteLine(a);//1    
a+="2";
Console.WriteLine(a);//12
大家可以看看下面生成的对应的IL代码,可以看到a+="2"并非是在原有分配的堆中进行修改,
而是创建了一个新的字符串;
而+在IL中也是使用Concat,将两个字符串联;
所以String的不可变就是当你在创建了字符串后其不可修改;
.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// 代码大小       34 (0x22)
.maxstack  2
.locals init ([0] string a)
IL_0000:  nop
IL_0001:  ldstr      "1"
IL_0006:  stloc.0
IL_0007:  ldloc.0
IL_0008:  call       void [mscorlib]System.Console::WriteLine(string)
IL_000d:  nop
IL_000e:  ldloc.0
IL_000f:  ldstr      "2"
IL_0014:  call       string [mscorlib]System.String::Concat(string,
string)
IL_0019:  stloc.0
IL_001a:  ldloc.0
IL_001b:  call       void [mscorlib]System.Console::WriteLine(string)
IL_0020:  nop
IL_0021:  ret
} // end of method Program::Main

2.当创建多个字符串内容相同的对象时,都只会指向同一个引用;

            string a = "11";
string b = "11";
string c = "11";
string d = "1";
d += "1";

a和b都指向同一个a的引用,并不会为b重新分配内存;这样即可保证内存有效利用;这一点用IL不是很好看出来,所以大家可以按下面方法去比较他们的引用地址,都是指向同一个堆;

Console.WriteLine(string.ReferenceEquals(a, b));
Console.WriteLine(string.ReferenceEquals(a, c));
Console.WriteLine(string.ReferenceEquals(c, b));
Console.WriteLine(string.ReferenceEquals(a, d));
Console.WriteLine(string.ReferenceEquals(b, d));
Console.WriteLine(string.ReferenceEquals(c, d));

运行结果:

   True
True
True
False
False
False
这说明当我们新建一个字符串以后,将为其分配内存,而之后如何有值和其相同的字符串不会被创建分配堆而是直接分配其引用;

3.字符串比较:

==和!=是为了比较String对象的值是否相同而不是比较引用;

例如等号首先是比较引用是否相同,因为引用相同值一定会相同,就避免了再去对值进行比较;

而引用如果不同再去比较值,相同则返回true;

总之==一定一定是为了比较字符串的值是否相同;

string s2 = new StringBuilder().Append("My").Append("Test").ToString();
string s3 = new StringBuilder().Append("My").Append("Test").ToString();
Console.WriteLine((object)s2==(object)s3);//False

上面是返回False,大家肯定有些迷惑,而此前一位园友则解释我也不尽赞同,这里只发表我的解释:

此处比较的是两个引用类型,为什么这么说,因为大家都知道引用地址都是存放在栈中

[1] [2] 下一页

分享给朋友:
您可能感兴趣的文章:
随机阅读: