字符串表现信息的能力非常强大。对于String,C#提供了很多基本方法,并且对其进行了优化,下面介绍下一些基础知识,可作为参考。
1. 常用方法
方法名 |
静态或实例方法 |
描述 |
Compare | 比较两个指定的 String 对象。 | |
CompareOrdinal | 通过计算每个字符串中相应 Char 对象的数值来比较两个 String 对象。 | |
CompareTo | 将此实例与指定的对象或 String 进行比较,并返回二者相对值的指示。 | |
Concat | 连接 String 的一个或多个实例,或 Object 的一个或多个实例的值的 String 表示形式。 | |
Contains | 返回一个值,该值指示指定的 String 对象是否出现在此字符串中。 | |
Copy | 创建一个与指定的 String 具有相同值的 String 的新实例。 | |
CopyTo | 将指定数目的字符从此实例中的指定位置复制到 Unicode 字符数组中的指定位置。 | |
EndsWith | 确定 String 的实例的末尾是否与指定的字符串匹配。 | |
GetEnumerator | 检索一个可以循环访问此字符串中的每个字符的对象。 | |
IndexOf | 报告 String 或一个或多个字符在此字符串中的第一个匹配项的索引。 | |
IndexOfAny | 报告指定 Unicode 字符数组中的任意字符在此实例中第一个匹配项的索引。 | |
Insert | 在此实例中的指定索引位置插入一个指定的 String 实例。 | |
Intern | 检索系统对指定 String 的引用。 | |
IsInterned | 检索对指定 String 的引用。 | |
Join | 在指定 String 数组的每个元素之间串联指定的分隔符 String,从而产生单个串联的字符串。 | |
LastIndexOf | 报告指定的 Unicode 字符或 String 在此实例中的最后一个匹配项的索引位置。 | |
LastIndexOfAny | 报告在 Unicode 数组中指定的一个或多个字符在此实例中的最后一个匹配项的索引位置。 | |
Normalize | 返回一个新字符串,其二进制表示形式符合特定的 Unicode 范式。 | |
PadLeft | 右对齐此实例中的字符,在左边用空格或指定的 Unicode 字符填充以达到指定的总长度。 | |
PadRight | 左对齐此字符串中的字符,在右边用空格或指定的 Unicode 字符填充以达到指定的总长度。 | |
Remove | 从此实例中删除指定个数的字符。 | |
Replace | 将此实例中的指定 Unicode 字符或 String 的所有匹配项替换为其他指定的 Unicode 字符或String。 | |
Split | 返回包含此实例中的子字符串(由指定 Char 或 String 数组的元素分隔)的 String 数组。 | |
Substring | 从此实例检索子字符串。 | |
StartsWith | 确定 String 实例的开头是否与指定的字符串匹配。 | |
ToCharArray | 将此实例中的字符复制到 Unicode 字符数组。 | |
ToLower | 返回此 String 对象的转换为小写形式的副本,返回时使用固定区域性的大小写规则。 | |
ToLowerInvariant | 将此实例的值转换为 String。 | |
ToUpper | 返回此 String 转换为大写形式的副本。 | |
ToUpperInvariant | 返回此 String 对象的转换为大写形式的副本,返回时使用固定区域性的大小写规则。 | |
Trim | 从此实例的开始位置和末尾移除一组指定字符的所有匹配项。 | |
TrimEnd | 从此实例的结尾移除数组中指定的一组字符的所有匹配项。 | |
TrimStart | 从此实例的开始位置移除数组中指定的一组字符的所有匹配项。 |
2. 不可变性
字符串是不可变的,也就是说,无论你对一个字符串做任何操作(增加字符、删除字符。。。),都不会改变它的值。问题是,我们不能改变它的值怎么操作字符串呢?解决方法就是创建一个新的字符串,把操作结果赋值给这个新的字符串。
3. 字符串池
由于经常用到字符串,难免出现大量重复的值。想要优化这种浪费内存的做法就是:建立一个池,把所有出现过的字符串都放在这里供程序使用。如果都是读取,无论从空间还是时间角度来看,那肯定大量提高性能。那如果修改呢?大家共享一个资源,通常情况下会造成多线程冲突。这里就有个nb的特性起作用了,就是字符串的不可变性。它不可变,就不存在操作冲突的情况了!!
4. 空间性能考虑
每次修改一个字符串都会产生新的string对象,可能会造成字符串对象大量产生带来的性能下降。比如,一万个a叠加的程序:
string result = "";
for (int i = 0; i < 10000; i++)
{
result += "a";
}
这段程序会产生1+2+3+…..+10000个字符串对象,“a”“aa”“aaa”aaaa“。。。。
对于这种性能的问题,解决的方式是使用StringBuilder。它对内部字符数据做修改,而不是产生数据副本,所以会节省大量空间。
StringBuilder result = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
result.Append("a");
}
通过ToString()方法,你可以得到10000个a长度的结果,最终只会产生2个对象,大大节省了内存空间。
5. 字符串拼接
通过“+”,可以直接拼接多个字符串。其实是重载了操作符,底层调用了String.Concat()方法。无论如何,这样的拼接会产生多个字符串结果。通过使用StringBuilder的Append方法来解决一般拼接造成的性能问题。
6. 转义字符“\”
- 输出特殊字符的字面值,比如单引号,双引号,反斜线等等。
- 特殊意义的字符,如\r,\n,\t等等
7. 逐字字符串“@”
可以是字符串中的转义字符实效,尝尝用在网络地址或者本地文件系统路径中。
8. 相等性
String重载了“==”操作符已经被重载,所以String的“==”并不是真的比较reference是否相等,而是比较了值,这和Equals方法一样。另外,一般来说,字面值一样的字符串,它们引用的都是字符串池中的对象实例,所以reference也是一样的。只有在使用new关键字创建一个String对象时,才会在托管堆上建立实例,拥有不用的reference,也就是用new关键字脱离了string池机制的范畴。