详解C#中的string与String
⽬录
⼩写 string 与⼤写 String
声明与初始化 string
string 的不可变性
正则 string 与原义 string
string 的转义序列
格式化字符串
操作⼦字符串
字符串的 null 与 ""(空)
可提⾼性能的 StringBuilder
序
字符串是 String 类型的对象,它的值是⽂本。在内部,⽂本被存储为 Char 对象的顺序只读集合。 C# 字符串末尾没有以 null 结尾的字符;因此 C# 字符串可以包含任意数⽬的嵌⼊式 null 字符(“\0”)。字符串的 Length 属性代表它包含的 Char 对象的数量,⽽不是Unicode 字符的数量。若要访问字符串中的各个 Unicode 码位,请使⽤ StringInfo 对象。
⼩写 string 与⼤写 String
在 C# 中,关键字 string 是 String 的别名。因此,String 与 string 等效,也就是说您想⽤哪个就⽤哪个。String 类提供了很多⽤于安全地创建、操作和⽐较字符串的⽅法。此外,C# 语⾔还重载某些运算符来简化常见的字符串操作。
声明与初始化 string
请看⽰例:
static void Main(string[] args)
{
// 声明但不初始化
string msg1;
// 声明并初始化为 null
string msg2 = null;
// 作为⼀个空字符串进⾏初始化,⽤ Empty(空)常量⽽不是字⾯值的 ""(空)
string msg3 = String.Empty;
// ⽤正则的字符串字⾯值进⾏初始化
string oldPath = "c:\\windows";
// 直接以字符串初始化
string newPath = @"c:\windows";
// 也可以使⽤ System.String
String content = "Hello World!";
// 使⽤ const 防⽌ msg4 被篡改
const string msg4 = "I'm const!";
// 可以使⽤隐式类型 var
var msg5 = "Hi!";
// 使⽤ String 构造器进⾏初始化
char[] letters = { 'A', 'B', 'C' };
string alphabet = new String(letters);
Console.Read();
}
【注意】除了在使⽤字符数组初始化字符串时以外,不要使⽤ new 运算符创建字符串对象。
使⽤ Empty 常量值初始化字符串可新建字符串长度为零的 String 对象。零长度字符串的字符串表⽰形式为 ""。使⽤ Empty 值(⽽不是 null)初始化字符串可以降低发⽣ NullReferenceException 的可能性。我们常常会在尝试访问字符串之前使⽤静态IsNullOrEmpty(String) ⽅法验证字符串的值。
string 的不可变性
字符串对象是不可变的:即它们创建之后就⽆法更改。所有看似修改字符串的 String ⽅法和 C# 中的运算符,实际上都以新字符串对象的形式返回结果。在下⾯的⽰例中,当连接 s1 和 s2 的内容以形成⼀个字符串时,不会修改两个原始字符串。 += 运算符会创建⼀个包含组合内容的新字符串。这个新对象赋给变量 s1,⽽最初赋给 s1 的对象由于没有其他任何变量包含对它的引⽤⽽释放,将在后续被垃圾回收。
⽰例⼀:
static void Main(string[] args)
{
var s1 = "Hi!";
var s2 = "Fanguzai!";
//拼接 s1 和 s2,并且修改 s1 指向的值
s1 += s2; //即 s1 = s1 + s2;
Console.WriteLine(s1);
Console.Read();
}
图:var s1 = "Hi!"; var s2 = "Fanguzai!";
图:s1 = s1 + s2; 重新修改 s1 的指向
由于“修改”字符串实际上是创建⼀个新字符串,因此创建对字符串的引⽤时必须谨慎。如果创建了对字
符串的引⽤,然后“修改”原始字符串,则该引⽤指向的仍是原始对象,⽽不是修改字符串时创建的新对象。
static void Main(string[] args)
{
var s1 = "Hi! ";
var s2 = s1;
//在 s1 重新赋值后,这次没有重新修改 s2 指向的值
s1 += "Fanguzai!"; //即 s1 = s1 + "Fanguzai!";
Console.WriteLine(s2);
Console.Read();
}
图:var s1 = "Hi!"; s2 = s1; 他们指向相同的引⽤地址
图:s1 = s1 + "Fanguzai!"; 会创建⼀个没有引⽤的 "Fanguzai!",并重新修改 s1 指向的值。正则 string 与原义 string
c++string类型如果必须嵌⼊ C# 提供的转义符,则应使⽤正则字符串:
static void Main(string[] args)
{
var coluString = "Col1\tCol2\tCol3";
var rowString = "Row1\r\nRow2\r\nRow3";
Console.WriteLine(coluString);
Console.WriteLine("=====");
Console.WriteLine(rowString);
Console.Read();
}
如果字符串⽂本包含反斜杠字符(例如在⽂件路径中),为⽅便起见和提⾼可读性,应使⽤原义字符串。由于原义字符串保留换⾏符作为字符串⽂本的⼀部分,因此可⽤于初始化多⾏字符串。在原义字符串中嵌⼊引号时请使⽤双引号。下⾯的⽰例演⽰原义字符串的⼀些常见⽤途:
static void Main(string[] args)
{
var path = @"C:\Windows";
var text = @"Are you Fanguzai?
I'm Fanguzai!";
Console.WriteLine(path);
Console.WriteLine("=====");
Console.WriteLine(text);
Console.Read();
}
string 的转义序列
【备注】编译时,原义字符串转换为所有转义序列均保持不变的普通字符串。因⽽,如果在调试器监视窗⼝中查看原义字符串,则看到的将是编译器添加的转义字符,⽽不是源代码中的原义版本。例如,原义字符串 @"C:\" 在监视窗⼝中将显⽰为
"C:\\"。
格式化字符串
格式字符串是内容可以在运⾏时动态确定的⼀种字符串。采⽤以下⽅式创建格式字符串:使⽤静态 Format ⽅法并在⼤括号中嵌⼊占位符,这些占位符将在运⾏时替换为其他值。
private static void Main(string[] args)
{
const string name = "Fanguzai";
var s = string.Format("Hi, {0}!", name); //使⽤占位符
Console.WriteLine(s);
Console.Read();
}
操作⼦字符串
⼦字符串是包含在字符串中的任意字符序列。使⽤ Substring ⽅法可以基于原始字符串的⼀部分创建新字符串。可以使⽤ IndexOf ⽅法搜索⼦字符串的⼀个或多个匹配项。使⽤ Replace ⽅法可将指定⼦字符串的所有匹配项替换为⼀个新字符串。与 Substring ⽅法⼀样,Replace 实际上返回的也是新字符串,⽽不修改原始字符串。
private static void Main(string[] args)
{
const string s1 = "Hi, Fanguzai!";
Console.WriteLine(s1.Substring(4)); //截取
Console.WriteLine(s1.Replace("Hi","Hello")); //替换
Console.WriteLine(s1.IndexOf(",", StringComparison.Ordinal)); //取索引
Console.Read();
}
字符串的 null 与 ""(空)
空字符串是不包含字符的 System.String 对象的实例。在各种编程⽅案中经常会使⽤空字符串表⽰空⽩⽂本字段。可以对空字符串调⽤⽅法,因为它们是有效的 System.String 对象。
var s = string.Empty;
相反,null 字符串并不引⽤ System.String 对象的实例,任何对 null 字符串调⽤⽅法的尝试都会⽣成 NullReferenceException。但是,可以在串联和⽐较操作中将 null 字符串与其他字符串⼀起使⽤。
private static void Main(string[] args)
{
const string s1 = "Hi, Fanguzai!";
string s2 = null;
var s3 = string.Empty;
var s4 = s1 + s2; //有值的字符串与 null 拼接
Console.WriteLine("s4: {0}", s4);
Console.WriteLine("");
var isTrue = (s2 == s3);
Console.WriteLine("isTrue: {0}", isTrue);
Console.WriteLine();
var s5 = s3 + s2;
Console.WriteLine("s5: {0}", s5);
Console.WriteLine();
Console.Read();
}
可提⾼性能的 StringBuilder
.NET 中的字符串操作已⾼度优化,⼤多数情况下不会显著影响性能。但在某些应⽤场景中,例如在执⾏数百甚⾄好⼏亿次的循环中,字符串操作很可能会影响性能。 StringBuilder 类创建了⼀个字符串缓冲区,⽤于在程序执⾏⼤量字符串操作时提供更好的性
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论