C# 中的字符串数据类型、不可变性和常见字符串操作
1. 字符串数据类型
在 C# 中,字符串数据类型是通过 string 关键字表示,它是 System.String 类的别名。字符串是一组字符的集合,常用于存储和操作文本。
- 声明与初始化:
- string text = "Hello, World!";
- 特点:
- 引用类型:string 是引用类型,但行为类似于值类型。
- 不可变性:字符串一旦创建,其内容无法更改。
2. 字符串的不可变性
- 不可变性定义: 在 C# 中,字符串是不可变的。任何修改字符串的操作实际上都会创建一个新的字符串实例,而不是修改原来的字符串。
- 优点:
- 线程安全:因为字符串不可变,所以在多线程环境中使用是安全的。
- 哈希一致性:字符串的不可变性使其在字典或集合中作为键时表现稳定。
- 内存优化:C# 使用字符串池(interning)技术共享相同内容的字符串。
- 示例:
- string original = "Hello"; string modified = original + " World"; // 创建了一个新字符串 Console.WriteLine(original); // 输出 "Hello",原字符串未变
3. 常见字符串操作
C# 提供了丰富的字符串操作方法,以下是一些常用操作。
(1) 字符串连接
- 使用 + 运算符:string firstName = "John"; string lastName = "Doe"; string fullName = firstName + " " + lastName;
- 使用 string.Concat:string fullName = string.Concat(firstName, " ", lastName);
- 使用 StringBuilder(适用于频繁的字符串操作):using System.Text; StringBuilder sb = new StringBuilder(); sb.Append("Hello"); sb.Append(", World!"); Console.WriteLine(sb.ToString()); // 输出 "Hello, World!"
(2) 字符串分割与合并
- 分割: 使用 Split 方法将字符串分割为数组:string sentence = "apple,banana,grape"; string[] fruits = sentence.Split(',');
- 合并: 使用 string.Join 方法将数组合并为字符串:string[] fruits = { "apple", "banana", "grape" }; string sentence = string.Join(", ", fruits);
(3) 字符串查找
- 索引查找: 使用 IndexOf 或 LastIndexOf:string text = "Hello, World!"; int index = text.IndexOf("World"); // 返回 7
- 判断是否包含: 使用 Contains:bool containsWord = text.Contains("World"); // 返回 true
(4) 字符串替换
使用 Replace 方法替换字符或子字符串:
string text = "Hello, World!";
string replaced = text.Replace("World", "C#");
Console.WriteLine(replaced); // 输出 "Hello, C#!"
(5) 字符串截取
- 使用 Substring 方法截取部分字符串:string text = "Hello, World!"; string sub = text.Substring(7, 5); // 从索引 7 开始,截取 5 个字符 Console.WriteLine(sub); // 输出 "World"
- 使用 Trim 去除空白:string text = " Hello, World! "; string trimmed = text.Trim(); // 去除两端空白
(6) 字符串比较
- 使用 Equals 方法进行字符串比较:string str1 = "hello"; string str2 = "HELLO"; bool isEqual = str1.Equals(str2, StringComparison.OrdinalIgnoreCase); // 忽略大小写
- 使用 Compare 方法进行排序:int result = string.Compare("apple", "banana"); // 返回负数表示 "apple" 小于 "banana"
(7) 字符串格式化
- 使用插值字符串:string name = "John"; int age = 30; string message = $"Name: {name}, Age: {age}";
- 使用 string.Format:string message = string.Format("Name: {0}, Age: {1}", name, age);
(8) 转换大小写
- 使用 ToUpper 和 ToLower:string text = "Hello, World!"; string upper = text.ToUpper(); // 转为大写 string lower = text.ToLower(); // 转为小写
4. 字符串池(String Interning)
C# 为了优化内存使用,会将相同内容的字符串存储到一个共享池中。字符串池的主要特性是相同的字面量字符串共享同一内存地址。
- 示例:
- string str1 = "Hello"; string str2 = "Hello"; Console.WriteLine(object.ReferenceEquals(str1, str2)); // 输出 true
- 注意:动态创建的字符串不会自动加入池中,可以使用 string.Intern 方法。
5. 示例代码:字符串操作
using System;
using System.Text;
class Program
{
static void Main()
{
// 字符串声明与连接
string greeting = "Hello";
string name = "World";
string message = $"{greeting}, {name}!";
Console.WriteLine(message);
// 字符串查找
int index = message.IndexOf("World");
Console.WriteLine($"Index of 'World': {index}");
// 替换
string replaced = message.Replace("World", "C#");
Console.WriteLine(replaced);
// 分割与合并
string[] words = message.Split(' ');
string joined = string.Join("-", words);
Console.WriteLine(joined);
// 使用 StringBuilder
StringBuilder sb = new StringBuilder("Start");
sb.Append(" - Middle");
sb.Append(" - End");
Console.WriteLine(sb.ToString());
}
}
6. 总结
- 不可变性:字符串的不可变性提高了安全性和性能,但在大量修改字符串的场景中可能导致内存开销。
- 常见操作:包括连接、查找、替换、分割、格式化等。
- 性能优化:对于频繁修改的场景,推荐使用 StringBuilder。在需要大量字符串比较时,尽量使用 StringComparison 提升效率。