string与StringBuilder

本文介绍了C#中string和StringBuilder的区别与用法,详细解释了string作为特殊引用类型的表现及其实现机制,并对比了StringBuilder在字符串拼接方面的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

string与StringBuilder

今天无意间看到C#6.0的新特性$”“的用法发现很神奇,就查看了很多资料,正好就对string型做一个整理

string是什么

说string之前,首先先介绍下Char。Char在.Net中表示字符,即一个16位的Unicode代码值,它是一个值类型并且长度固定。而string被称为字符串,可以理解成多个字符的集合,它是特殊的引用类型。它继承自System.Object肯定是个引用类型,但是在应用表现上又凸现出值类型的特点,因为string不能改变自身的值,如果用string的话,函数调用之后string的值不会发生改变,代码中改变它的值实际上是新实例化了一个string变量。

Console.Write("a" +"b"); //输出ab
Console.Write('a'+'b'); //输出195其中'a'=97'b'=98
Console.Write(string.Concat('a' ,'b')); //输出ab

虽然string是引用类型,但是我们不关心string变量的地址,只关心它的值,如果多个string对象引用同一个地址,当其中的某个对象改变时,使得此改变不会影响到其他对象。然而如果每次都实例化同一个值的string变量,会造成内存浪费,因此CLR默默地维护了一个叫做驻留池(Intern Pool)的表。这个表记录了所有在代码中使用字面量声明的字符串实例的引用。CLR在为i.ToString()方法的返回值分配内存时,并不会到驻留池中去检查是否有值为“1”的字符串已经存在了,所以自然不会让s2指向驻留池内的对象。为了让编程者能够强制CLR检查驻留池,以避免冗余的字符串副本,String类的设计者提供了一个名为Intern的类方法。

可以使用ReferenceEquals查看是否是同一个引用。注意:ReferenceEquals只能用于引用类型的比较,值类型一律返回FALSE。

int i = 1;
string s1 = "12";
string s2 = "1";
string s3 = "1" + "2"; //s1,s3是同一个引用
string s4 = s2 + "2"; //s3,s4不是同一个引用
string s5 = string.Concat("1", "2"); //s3,s4,s5都不是同一个引用
string s6 = i.ToString();
string s7 = new string(s2.ToArray()); //s2,s6,s7都不是同一个引用
string s8 = string.Intern(s5); //s1,s3,s8是同一个引用

字符串格式化

字符串格式化有两种方法一种是string.Format(),还有一种是$”“的方式,具体以下面这个例子来说明。

int a = 1,b=2,c=3;
string s1 = string.Format("Hello {0}{1}{2}", a, b, c);
string s2 = $"Hello {a}{b}{c}"; //s1与s2值相等,不是同一个引用

上面举的字符串拼接的例子,实际上拼接得到的是一个新的字符串,而原有的字符串和仍然存在,这在对字符串进行大量修改的场合,会导致严重的资源浪费。

而C#中采用StringBuilder解决这个问题。对StringBuilder的操作,如拼接Append(),插入Insert(),删除Remove(),替换Replace(),都是对现有的字符串进行操作,而不会引入新的字符串,避免了新建string类所造成的系统开销。

StringBuilder的用法

StringBuilder对象在做字符串连接操作时是在原来的字符串上进行修改,改善了性能。这一点我们平时使用中也许都知道,连接操作频繁的时候建议使用StringBuilder对象。但同时,在任何地方都使用StringBuilder是不恰当的做法。

从逻辑上说,StringBuilder对象包含一个字段,该字段引用了有Char结构构成的一个数组。可利用StringBuilder的各个成员来操作这个字符数组,高效率的缩短或更改字符串中的字符。如果字符串变大,超过已分配的字符数组的大小,StringBuilder会自动分配一个新的、更大的数组,复制字符,并开始使用新数组。前一个数组会被垃圾回收。

修改字符串

Append 方法可用来将文本或对象的字符串表示形式添加到由当前 StringBuilder 对象表示的字符串的结尾处。下面的示例将一个 StringBuilder 对象初始化为“Hello World”,然后将一些文本追加到该对象的结尾处。将根据需要自动分配空间。

StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Append(" What a beautiful day.");
Console.WriteLine(MyStringBuilder); //输出Hello World! What a beautiful day. 

Insert 方法将字符串或对象添加到当前 StringBuilder 中的指定位置。下面的示例使用此方法将一个单词插入到 StringBuilder 的第六个位置。

StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Insert(6,"Beautiful ");
Console.WriteLine(MyStringBuilder); //输出Hello Beautiful World! 

可以使用 Remove 方法从当前 StringBuilder 中移除指定数量的字符,移除过程从指定的从零开始的索引处开始。下面的示例使用 Remove 方法缩短 StringBuilder。

StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Remove(5,7); //第5个位置,长度为7
Console.WriteLine(MyStringBuilder); //输出Hello

Replace使用 Replace 方法,可以用另一个指定的字符来替换 StringBuilder 对象内的字符。下面的示例使用 Replace 方法来搜索 StringBuilder 对象,查找所有的感叹号字符 (!),并用问号字符 (?) 来替换它们。

StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Replace('!', '?');
Console.WriteLine(MyStringBuilder); //输出Hello World? 

将Stringbuilder串转换为string形式,通过ToSting方法,会创建新的string对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值