1. 概述
在 C# 中,string
是一个引用类型
,用于表示文本数据。字符串是由 Unicode 字符组成的不可变序列。这意味着一旦创建了一个字符串对象,其内容就不能被改变。
2. 特性
• 不可变性
:字符串对象一旦创建,其内容不能被改变。任何对字符串的修改操作都会返回一个新的字符串对象,而不会修改原始字符串。
• 引用类型
:虽然字符串通常像值类型一样使用,但它实际上是引用类型。这意味着字符串变量实际上存储的是字符串对象的引用。
• 空字符串
:string.Empty 表示一个空字符串,而不是 null。
• 字符串池
:C# 使用字符串池来优化内存使用。相同的字符串字面量会共享同一个内存位置。
• 索引访问
:可以通过索引访问字符串中的单个字符。
• 字符串方法
:string 类提供了丰富的静态和实例方法,用于字符串操作,如连接、分割、替换、格式化等。
3.常用功能及示例
1. 字符串连接
string str1 = "Hello";
string str2 = "World";
string result1 = str1 + " " + str2;
Console.WriteLine(result1); // 输出: Hello World
string result2 = $"{str1} {str2}";//建议使用干方式连接字符
Console.WriteLine(result2); // 输出: Hello World
2. 字符串长度
string str = "Hello";
int length = str.Length;
Console.WriteLine(length); // 输出: 5
3. 字符串比较
string str1 = "Hello";
string str2 = "hello";
bool isEqual = string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine(isEqual); // 输出: True
4. 字符串查找
string str = "Hello, World!";
int index = str.IndexOf("World");
Console.WriteLine(index); // 输出: 7
5. 字符串替换
string str = "Hello, World!";
string result = str.Replace("World", "C#");
Console.WriteLine(result); // 输出: Hello, C#!
6. 字符串分割
string str = "Hello,World,C#";
string[] parts = str.Split(',');
foreach (var part in parts)
{
Console.WriteLine(part); // 输出: Hello, World, C#
}
7. 字符串截取
string str = "Hello, World!";
string result = str.Substring(7, 5);
Console.WriteLine(result); // 输出: World
8. 字符串转小写
string str = "HELLO, WORLD!";
string lowerCase = str.ToLower();
Console.WriteLine(lowerCase); // 输出: hello, world!
9. 字符串转大写
string str = "hello, world!";
string upperCase = str.ToUpper();
Console.WriteLine(upperCase); // 输出: HELLO, WORLD!
10. 字符串修剪
string str = " Hello, World! ";
string trimmed = str.Trim();
Console.WriteLine(trimmed); // 输出: Hello, World!
11. 字符串格式化
string name = "Alice";
int age = 30;
string result = string.Format("Name: {0}, Age: {1}", name, age);
Console.WriteLine(result); // 输出: Name: Alice, Age: 30
12. 字符串拼接
List<string> words = new List<string> { "Hello", "World", "C#" };
string result = string.Join(", ", words);
Console.WriteLine(result); // 输出: Hello, World, C#
13. 字符串是否为空或空字符串
string str1 = "";
string str2 = null;
bool isNullOrEmpty1 = string.IsNullOrEmpty(str1);
bool isNullOrEmpty2 = string.IsNullOrEmpty(str2);
Console.WriteLine(isNullOrEmpty1); // 输出: True
Console.IsNullOrWhiteSpace(isNullOrEmpty2); // 输出: True
14. 字符串是否为空或空白字符串
string str1 = " ";
string str2 = null;
bool isNullOrWhiteSpace1 = string.IsNullOrWhiteSpace(str1);
bool isNullOrWhiteSpace2 = string.IsNullOrWhiteSpace(str2);
Console.WriteLine(isNullOrWhiteSpace1); // 输出: True
Console.WriteLine(isNullOrWhiteSpace2); // 输出: True
15. 字符串编码转换
string str = "Hello, 世界!";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
string result = System.Text.Encoding.UTF8.GetString(bytes);
Console.WriteLine(result); // 输出: Hello, 世界!
16. 字符串反转
string str = "Hello";
char[] charArray = str.ToCharArray();
Array.Reverse(charArray);
string result = new string(charArray);
Console.WriteLine(result); // 输出: olleH
17. 字符串插入
string str = "HelloWorld";
string result = str.Insert(5, ", ");
Console.WriteLine(result); // 输出: Hello, World
18. 字符串删除
string str = "Hello, World!";
string result = str.Remove(5, 2);
Console.WriteLine(result); // 输出: Hello World!
19. 字符串复制
string str = "Hello";
string copy = string.Copy(str);
Console.WriteLine(copy); // 输出: Hello
20. 字符串哈希码
string str = "Hello";
int hashCode = str.GetHashCode();
Console.WriteLine(hashCode); // 输出: 哈希码值
21. 字符串的性能优化
使用 StringBuilder 来构建和修改字符串,以提高性能。
using System.Text;
StringBuilder sb = new StringBuilder();
sb.Append("Hello, ");
sb.Append("World!");
string result = sb.ToString();
Console.WriteLine(result); // 输出: Hello, World!
4.稍微复杂一点的功能及示例
1. 正则表达式匹配
using System.Text.RegularExpressions;
string input = "The quick brown fox jumps over the lazy dog.";
string pattern = @"\b\w{4}\b"; // 匹配四个字母的单词
MatchCollection matches = Regex.Matches(input, pattern);
foreach (Match match in matches)
{
Console.WriteLine(match.Value); // 输出: quick, over, lazy
}
2. 正则表达式替换
using System.Text.RegularExpressions;
string input = "The quick brown fox jumps over the lazy dog.";
string pattern = @"\b\w{4}\b"; // 匹配四个字母的单词
string result = Regex.Replace(input, pattern, "****");
Console.WriteLine(result); // 输出: The **** brown fox jumps **** the **** dog.
3. 字符串解析
string input = "Name: Alice, Age: 30, City: New York";
string[] parts = input.Split(new[] { ',', ':' }, StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, string> data = new Dictionary<string, string>();
for (int i = 0; i < parts.Length; i += 2)
{
string key = parts[i].Trim();
string value = parts[i + 1].Trim();
data[key] = value;
}
foreach (var item in data)
{
Console.WriteLine($"{item.Key}: {item.Value}"); // 输出: Name: Alice, Age: 30, City: New York
}
4. 字符串格式化日期
using System;
DateTime date = DateTime.Now;
string formattedDate = date.ToString("yyyy-MM-dd HH:mm:ss");
Console.WriteLine(formattedDate); // 输出: 当前日期和时间的格式化字符串
5. 字符串加密和解密
using System.Security.Cryptography;
using System.Text;
public static string Encrypt(string plainText, string key)
{
using (Aes aesAlg = Aes.Create())
{
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] iv = new byte[16]; // 初始化向量
aesAlg.Key = keyBytes;
aesAlg.IV = iv;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(plainText);
}
return Convert.ToBase64String(ms.ToArray());
}
}
}
}
public static string Decrypt(string cipherText, string key)
{
using (Aes aesAlg = Aes.Create())
{
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] iv = new byte[16]; // 初始化向量
aesAlg.Key = keyBytes;
aesAlg.IV = iv;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (MemoryStream ms = new MemoryStream(cipherBytes))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
return sr.ReadToEnd();
}
}
}
}
}
string plainText = "Hello, World!";
string key = "ThisIsASecretKey123";
string encryptedText = Encrypt(plainText, key);
string decryptedText = Decrypt(encryptedText, key);
Console.WriteLine($"Original: {plainText}");
Console.WriteLine($"Encrypted: {encryptedText}");
Console.WriteLine($"Decrypted: {decryptedText}");
6. 多线程处理字符串
using System.Threading.Tasks;
string input = "The quick brown fox jumps over the lazy dog.";
string[] words = input.Split(' ');
Parallel.ForEach(words, word =>
{
Console.WriteLine(word);
});
7. 字符串排序
string input = "The quick brown fox jumps over the lazy dog.";
string[] words = input.Split(' ');
Array.Sort(words);
foreach (var word in words)
{
Console.WriteLine(word); // 输出: The, brown, dog., fox, jumps, lazy, over, quick, the
}
8. 字符串去重
string input = "The quick brown fox jumps over the lazy dog.";
string[] words = input.Split(' ');
var uniqueWords = new HashSet<string>(words);
foreach (var word in uniqueWords)
{
Console.WriteLine(word); // 输出: The, quick, brown, fox, jumps, over, the, lazy, dog.
}
9. 字符串分组
string input = "The quick brown fox jumps over the lazy dog.";
string[] words = input.Split(' ');
var groupedWords = words.GroupBy(word => word[0]);
foreach (var group in groupedWords)
{
Console.WriteLine($"Group: {group.Key}");
foreach (var word in group)
{
Console.WriteLine(word);
}
}
10. 字符串压缩和解压
using System.IO.Compression;
using System.IO;
public static string Compress(string text)
{
byte[] buffer = Encoding.UTF8.GetBytes(text);
using (var memoryStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimal))
{
gzipStream.Write(buffer, 0, buffer.Length);
}
return Convert.ToBase64String(memoryStream.ToArray());
}
}
public static string Decompress(string compressedText)
{
byte[] buffer = Convert.FromBase64String(compressedText);
using (var memoryStream = new MemoryStream(buffer))
{
using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
using (var streamReader = new StreamReader(gzipStream, Encoding.UTF8))
{
return streamReader.ReadToEnd();
}
}
}
}
string originalText = "The quick brown fox jumps over the lazy dog.";
string compressedText = Compress(originalText);
string decompressedText = Decompress(compressedText);
Console.WriteLine($"Original: {originalText}");
Console.WriteLine($"Compressed: {compressedText}");
Console.WriteLine($"Decompressed: {decompressedText}");
5.使用注意事项
1. 不可变性
• 性能影响:频繁修改字符串会导致大量临时对象的创建,增加内存开销和垃圾回收的压力。对于频繁修改的字符串,建议使用 StringBuilder。
• 示例:
string s = "Hello";
s += " World"; // 实际上创建了新的字符串对象
2. 字符串池
• 字符串池:编译器会将相同的字符串字面量放入字符串池中,以节省内存。
• 示例:
string s1 = "Hello";
string s2 = "Hello";
bool areSame = object.ReferenceEquals(s1, s2); // true
3. 空字符串与 null
• 空字符串:string.Empty 表示一个空字符串,长度为 0。
• null:表示没有引用任何字符串对象。
• 示例:
string empty = string.Empty;
string nullString = null;
bool isEmpty = string.IsNullOrEmpty(empty); // true
bool isNull = string.IsNullOrEmpty(nullString); // true
4. 字符串比较
• 区分大小写:默认情况下,字符串比较是区分大小写的。
• 不区分大小写:使用 StringComparison.OrdinalIgnoreCase 或 StringComparer.OrdinalIgnoreCase 进行不区分大小写的比较。
• 示例:
string s1 = "Hello";
string s2 = "hello";
bool areEqual = string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase); // true
- 字符串格式化
• string.Format:用于格式化字符串。
• 插值字符串:使用 $ 符号进行字符串插值。
• 示例:
string name = "Alice";
int age = 30;
string formatted = string.Format("Name: {0}, Age: {1}", name, age);
string interpolated = $"Name: {name}, Age: {age}";
6. 字符串分割和连接
• Split:将字符串分割成多个子字符串。
• Join:将多个子字符串连接成一个字符串。
• 示例:
string input = "Hello,World,C#";
string[] parts = input.Split(',');
string joined = string.Join(", ", parts);
7. 字符串编码
• 编码转换:使用 System.Text.Encoding 类进行字符串的编码和解码。
• 示例:
string str = "Hello, 世界!";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
string result = System.Text.Encoding.UTF8.GetString(bytes);
8. 异常处理
• 空指针异常:访问 null 字符串的属性或方法会引发 NullReferenceException。
• 示例:
string nullString = null;
try
{
int length = nullString.Length; // 抛出 NullReferenceException
}
catch (NullReferenceException ex)
{
Console.WriteLine("字符串为空");
}
9. 性能优化
• StringBuilder:对于频繁修改的字符串,使用 StringBuilder 可以显著提高性能。
• 示例:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
sb.Append(i.ToString());
}
string result = sb.ToString();
10. 字符串正则表达式
• 预编译正则表达式:对于频繁使用的正则表达式,可以预编译以提高性能。
• 示例:
using System.Text.RegularExpressions;
Regex regex = new Regex(@"\b\w{4}\b", RegexOptions.Compiled);
string input = "The quick brown fox jumps over the lazy dog.";
MatchCollection matches = regex.Matches(input);
foreach (Match match in matches)
{
Console.WriteLine(match.Value); // 输出: quick, over, lazy
}
11. 字符串资源管理
• 国际化和本地化:使用资源文件(.resx)来管理不同语言的字符串,以便支持多语言应用。
• 示例:
using System.Resources;
using System.Globalization;
ResourceManager rm = new ResourceManager("MyApp.Resources", Assembly.GetExecutingAssembly());
string greeting = rm.GetString("Greeting", new CultureInfo("fr-FR"));
Console.WriteLine(greeting); // 输出: Bonjour
12. 字符串安全
• 防止注入攻击:在处理用户输入时,特别是用于 SQL 查询或命令行参数时,使用参数化查询或转义特殊字符,以防止 SQL 注入或命令注入。
• 示例:
using System.Data.SqlClient;
string userInput = "userInput";
string query = "SELECT * FROM Users WHERE Username = @Username";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@Username", userInput);
// 执行查询
}
13. 字符串比较
• 文化敏感性:在进行字符串比较时,考虑文化差异,使用适当的 StringComparison 枚举值。
• 示例:
string s1 = "strasse";
string s2 = "straße";
bool areEqual = string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase); // false
bool areEqualWithCulture = string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase | StringComparison.CultureInfoIgnoreCase); // true
14. 字符串长度
• 最大长度:C# 中的字符串最大长度受系统内存限制,但通常可以达到 2GB。
• 检查长度:在处理长字符串时,确保检查字符串长度,避免超出预期。
• 示例:
string longString = new string('a', int.MaxValue - 100);
if (longString.Length > 1000000)
{
Console.WriteLine("字符串过长");
}
15. 字符串格式化
• 自定义格式化:使用自定义格式化字符串来控制输出格式。
• 示例:
double number = 123456.789;
string formatted = number.ToString("N2"); // 输出: 123,456.79
16. 字符串编码
• 多字节字符:处理多字节字符(如中文、日文等)时,确保使用正确的编码方式。
• 示例:
string chineseString = "你好,世界!";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(chineseString);
string result = System.Text.Encoding.UTF8.GetString(bytes);
17. 字符串缓存
• 缓存常用字符串:对于频繁使用的字符串,可以考虑缓存以提高性能。
• 示例:
private static readonly string CachedString = "Frequently used string";
public void UseCachedString()
{
Console.WriteLine(CachedString);
}
18. 字符串搜索
• 高效搜索:使用 IndexOf 方法进行字符串搜索,注意区分大小写和文化敏感性。
• 示例:
string input = "Hello, World!";
int index = input.IndexOf("World", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(index); // 输出: 7
6.实践总结(实在写不完根本,写不完)
1. 使用 StringBuilder 进行频繁的字符串拼接。
2. 处理用户输入时注意安全问题,防止注入攻击。
3. 使用资源文件进行国际化和本地化。
4. 考虑文化差异进行字符串比较。
5. 检查字符串长度,避免超出预期。
6. 使用自定义格式化字符串控制输出格式。
7. 处理多字节字符时使用正确的编码方式。
8. 缓存常用字符串以提高性能。
9. 使用 IndexOf 方法进行高效的字符串搜索。
10. 预编译正则表达式以提高性能。