字符串

2005年2月7日21:56:16

字符串

字符串在C#中是System.String(或简化为小写string)类的一个实例,它表示一个不变的字符序列。字符串创建的语法很简单:string s =“C# Sharp XP”, 即在托管堆上创建了内容为字符串“C# Sharp XP”的内存区域,而s仅仅是指向该内存区域的一个引用句柄。

看下面的代码:
string s1=“Hello,World!”;
string s2=s1;


这时,s1和s2都指向同一块含“Hello,World!”的内存区。

C#为字符串提供了两种转义表达。第一种和传统C/C++中的转义字符表达相同,即用反斜线“/”加特定字符的表达方式。如“/t”表示Tab键,“/r”表示回车,“/n”表示换行等等。要表示C盘“我的文档”下的一个文件路径:string MyPath=“C://Documents and Settings//Cornfield//My Documents//MyFile.cs”,其中双斜线被转义为单斜线。而采用第二种表示方法,可以在字符串前加一个“@”符号,这样就可按正常的字符序列来表达字符串,如上面的文件路径可以像这样来表达:string MyPath=@“C:/Documents and Settings/Cornfield/My Documents/MyFile.cs”,和前面的表达效果相同。第二种表示方法在我们表达包含特殊字符的长字符串的情况下非常有用,它甚至能够表达不能显示为字符形式的回车、换行等特殊字符。

可以通过索引器来获取字符串中的单个字符(16位Unicode编码)——这和C/C++中的字符串数组在本质上是完全不同的。下面的代码演示了这一点:
string s =“C# Sharp XP”;
for (int index = 0; index < s.Length; index++)
Console.WriteLine(s[index]);


由于字符串恒定性的缘故,我们不能做类似s[index]=‘p’的改变,这是由System.String的只读索引器public char this[int index] {get;}来保证的。

作为System.String类型的实例,系统为字符串提供了丰富多样的操作,这里只对几个比较特殊的方法做一剖析。String类实现了ICloneable接口,但String.Clone方法并不是返回一个新创建的String实例,而是仅仅返回一个和参数一样的引用句柄,也就是说“string s2=s1.Clone()”和前面的“string s2=s1”效果一样。需要返回一个和参数内容一样,但引用句柄不同的字符串可以采用静态的String.Copy方法。实例方法System.Equal和类操作符“public static bool operator ==(string a,string b);”比较的都是两个字符串的内容是否相等,而非引用句柄。

下面的代码示例,集中展示了上述方法的行为:
using System;
class Test
{
    public static void Main()
    {
 string s1=“Hello,World!”;
 string s2=s1.Clone().ToString();
 //克隆,句柄相等,内容相等
 string s3 = string.Copy(s1);
 // 拷贝,句柄不等,内容相等
 Console.WriteLine(s1==s2);
 //True,内容相等
 Console.WriteLine(s1==s3);
 //True,内容相等
 Console.WriteLine((object)s1==(object)s2);
 //True,句柄引用相等
 Console.WriteLine((object)s1==(object)s3);
 //False,句柄引用不等
    }
}


字符串恒定性

字符串的恒定意思是指一旦字符串的值(System.String实例)被创建后,它便不可以改变。

看下面一段典型的代码:
string s1=“Hello,”;
string s2=“World!”;
s1+=s2;


上面的语句执行完后,s1为“Hello,World!”,s2为“World!”。但s1原来的值“Hello”并没有因此消失,确切地讲“Hello”仍然占有内存空间,只不过现在不能被我们引用到而已,它只能等待.NET的自动垃圾收集器来回收其资源,这在以前的C++中就造成了内存泄漏,也就是说在上面的语句执行后,我们将拥有“Hello,World!”(s1引用句柄指向的值),“World!”(s2引用句柄指向的值),“Hello,”(没有引用句柄指向该值)共三个存储字符串的内存区。

字符串值恒定的特征还表现在作为string类型的参数传递上,我们看下面的例子:
using System;
class Test
{
public static void Main()
{
string p=“Hello,”;
MyMethod(p);
Console.WriteLine(p);//输出“Hello,”
}
public static void MyMethod(string p)
{
p+=“World!”;
Console.WriteLine(p);//输出Hello,World!
}
}


虽然说string类型在C#中是一种引用类型,但由于字符串的恒定性质,方法MyMethod并没有改变传进来的p的引用句柄(若要改变则需要采用ref关键字修饰参数),而这个引用句柄本身指向的表达字符串“Hello,”的内存区域也没有改变,自然通过MyMethod方法的调用字符串p也就不会改变。

理解字符串值恒定的特征对我们在C#中熟练操作字符串非常重要,比如System.String类的很多方法实际上并没有改变参与操作的字符串本身,而是创建一个新值,仅仅把原来的字符串留给自动垃圾收集器。如果C#程序中频繁地操作字符串,很有可能引起字符串大量的“创建/丢弃”动作,势必给系统造成负担,这时我们应该借助于StringBuilder类。StringBuilder位于System.Text命名空间下,它的实例不是字符串,但它为可变字符串提供了丰富的操作: 插入,追加,替换,删除等,同时由于它的操作发生在同一块内存区,因此没有恒定字符串System.String频繁地“创建/丢弃”的消耗,可以非常方便地利用构造器“public StringBuilder(string value);”来创建含有value字符串值的StringBuilder类实例,同样可以用StringBuilder的实例方法ToString非常方便地得到类型为string的字符串的内容。和System.String类的很多方法相反,StringBuilder类的方法改变的正是参与操作的StringBuilder类实例本身,并不创建新值!

作为一个一般性的原则,如果仅仅涉及到字符串的内容表示或者创建新的字符串,往往采用System.String的方法就可以了,但如果涉及到大量的字符串内容的变更操作时,就很有必要采用StringBuilder类的一些相关方法,然后再调用ToString方法得到我们需要的字符串。
 
1、从字符串中提取子串
StringBuilder 类没有支持子串的方法,因此必须用String类来提取。
string mystring="My name is ynn.";
//Displays "name is ynn."
Console.WriteLine(mystring.Substring( 3 ));
//Displays "ynn"
Console.WriteLine(mystring.Substring( 11,3 ));


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值