学习C#有一段时间了。可是在string和char这里却很迷糊。于是做了一些测试来深入了解。
说内容之前
string
1、string在c#中比较特殊。虽然string是引用类型。但是却可以用来和值一样来比较数值。先看下面代码
为何结果这样。因为c#中专门会string开辟了一块存储堆,当给string赋值时自动会在这块内存中寻找这个值,如果有,直接把这个地址给string如果没有,就在查快存储堆中存下这个值。所以s3和s4不管内容还是地址完全相同。
2、如果string不是直接赋值而是动态赋值则会在新开辟一个堆空间来存放内容。看下面测试
有很多人会疑惑,为何==这里会显示true而不是false呢,不是说是新开辟一个堆来存放的吗?难道==判断的不是地址码?答案是对的。
可以很明确的看到RefenceEquals得到的结果是false说明地址(引用)肯定不一样,为何==是true呢。因为在c#中string中对==进行了重写和Equals完全一模一样比的是值。
从而得到两个结论:1、动态赋值即使内容一样,地址也不同。2、string的比较==已经重写,比的是内容。
char[]数组
1、字符数组和字符串虽然都是引用类型,但是char[]就是没有对==重写,所以==比较的是两边的引用。
从上面可以看出两个数组c1和c3虽然内容一样但是引用不同,所以c1==c3是false,ReferenceEquals(c1,c3)也是false,但是为何c1.Equals(c3)也是false呢?难道c1和c3内容不相等?都不是。因为这里的Equals继承自Object,自定义数组中并没有对这个equals重写,所以这里的equals比较的是两个object,所以是不同的。
那么想要比较两个数组的内容是否相等怎么做呢。那就要自己写方法了,用循环判断两个数组的每个成员是否相等。
2、char[]的每个单独成员是字符char值类型。
从上可以看出c1[0]和c3[0]的值都是‘a’,并且都是值类型。所有两者==和Equals都是true,但是因为两个值存在不同的对
3、因为char[]是引用类型,所以当把一个数组赋值给另一个数组,给的是地址。当其中一个数组的存储空间上的值发生了改变另外一个数组内容也一样改变。
4、字符串虽然可以像值类型一样进行比较,但是本质还是引用类型。所以当把一个字符串str1赋值给另一个字符串str2的时候,给的还是地址。注意如果str2=str1+"ab"是动态赋值,前面已经说过会单独开辟空间来存储和str2=str1不同。
从上面可以看出s5=s4给的是地址。所以两者的ReferenceEquals结果是true。但是当s4=“efg”的时候是在string专用堆上找到(找不到就新建)一个存着“efg”的空间来赋值给s4。所以才会出现s5依然是“abc”而不是也变成了“efg”。
相信通过上面的仔细比对。应该会有对c#中string和char[]更深的了解。