string不完全手册
string 引用类型,,还是值类型 ??
首先string类型肯定是引用类型,应为它自己继承自object类型,,由于它的特殊性,它有表现了一些值类型的特点. 比如 重载了==, 比较两个字符串的内容,而不是地址
为什么不将string设置成值类型呢?
我的理解是:
string经常要被多个地方用到,如果每个对象保存String的一份Copy,则会消耗大量内存, 而且我们使用string是只关心它的内容,不关心此对象,因此每个对象保存一个它的Copy是没有意义的.
为什么string很多时候表现出值类型的特点呢?
我的理解是:
1. 重写 equal, 那是因为我们不关心string变量的地址,只关心它的值.
2. string设计成不变性
为什么string具有不变性呢?
我的理解是:
1.不可改变的一个优点是它是线程安全的。
2.再者string是最常用来作为集合(Map,Hashtable) 键值得类型,而一旦一个String对象被用作集合的键值,改变String的内容就会破坏集合的语义,造成程序错误。
3.如果多个string对象引用同一个地址,当其中的某个对象改变时,使得此改变不会影响到其他对象,否则系统很容易rush.
4.我们一般只关系string的值
String作为参数传递的是什么?
按地址传递,而非值传递.






















理由: 引用类型按引用传递,值类型按值传递,这些都不错。 【这里表达是有误,引用类型传递的应该是此变量的值,只不过这个变量保存的是引用类型的地址,这是个Pointer,这个不算是引用传递,也叫值传递。 在函数里面拷贝了一份变量的值,指向的仍然是这个引用类型的地址】 [修改于2007年10月24日]
一个引用类型,比如System.Array类,作为参数向一个方法传递时,传送的是指针,但是这两种代码是不是就意味着等效?
void Test(Array a)和void Test(ref Array a)结果是并不完全等效。
如果在函数内部调用构造函数新建了对象并赋予参数,则函数外的变量不会受影响;
比如a = new ...
如果只是改动该参数(一个对象)的字段,则会有影响,此时加不加ref都是等效的。
比如a[i] = ...
而string类型的另外一个特殊性在于它是“不会变”的,每次操作string,都相当于新建了一个string对象,所以对于string来讲,void Test(String s)和void Test(ref String s)永远都是不一样的。在这里string再次表现出了值类型的特点,我们以为这是传值 - 实际上传送的还是地址,但是在操作的时候string被再次初始化,外部根本不能得到这个变化。
对于变量作用域的概念来讲,微软这么设计也是合理的:既然是函数内部建立的对象,外部就应该没有访问这个对象的能力,函数结束后,这些对象就会被GC收集,同样不会影响外面的程序。
字符串驻留:
如果内存上保留多个”Hello”实例,对内存是种浪费.如果在内存中只存储一个”Hello”字符串,并且所有对”Hello”字符串的引用都指向该字符串对象,就会提供内存效率.
String s = “hello”;
Object.ReferenceEquals(“hello”, s)); // true;
当CLR初始化时,它会创建一个内部散列表,其中键为字符串,值为指向托管堆中字符串对象的引用.当JIT编译时,它会在散列表中查找每一个文本常量字符串.
如果我们动态创建字符串呢?
string s1 = "Hello";
string s2 = "Hel";
string s3 = s2 + "lo";
string s5 = "Hel" + "lo";
string s4 = string.Intern(s2 + "lo");
Console.WriteLine(object.ReferenceEquals(s1, s3)); //output: False
Console.WriteLine(s1.Equals(s3)); //output: True
Console.WriteLine(object.ReferenceEquals(s1, s4)); //output: True
Console.WriteLine(object.ReferenceEquals(s1, s5)); //output: True
因为s3是被动态创建的它并没有添加到CLR内部散列表中.
垃圾回收器不会释放CLR内部的散列表中引用的字符串对象,只有当整个进程中所有的应用程序域都不再引用这个字符串时,它们才被释放.
通过字符表达式计算出表达式结果:









【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?