1️⃣ 基础概念:string 与 CultureInfo
-
string是 不可变的 Unicode 字符序列(UTF-16)。 -
string本身不包含文化信息,只是字符集合。 -
CultureInfo 是 .NET 中表示"文化/地区/语言环境"的类,例如:
csharpvar enUS = new CultureInfo("en-US"); // 美国英语 var trTR = new CultureInfo("tr-TR"); // 土耳其语 -
支持文化的意义:在不同语言环境下,字符串的 排序、比较、大小写转换 规则可能不同。
2️⃣ 文化敏感操作 API
C# 提供了多种 可传入 CultureInfo 的字符串操作:
2.1 字符串比较
csharp
int string.Compare(string strA, string strB, bool ignoreCase, CultureInfo culture)
-
ignoreCase→ 是否忽略大小写 -
culture→ 使用哪种文化规则 -
返回:
<0→ strA 排在 strB 前0→ 相等>0→ strA 排在 strB 后
例子:土耳其语的 I 与 i
csharp
string a = "i";
string b = "I";
CultureInfo en = new CultureInfo("en-US");
CultureInfo tr = new CultureInfo("tr-TR");
Console.WriteLine(string.Compare(a, b, false, en)); // -1
Console.WriteLine(string.Compare(a, b, false, tr)); // -1
Console.WriteLine(string.Compare(a, b, true, tr)); // 0
土耳其文化中,"i"的大写是 "İ",而英语是 "I"。CultureInfo 确保比较符合当地规则。
2.2 排序(Sort)
Array.Sort或 LINQ 排序可以用StringComparer。StringComparer内部依赖CultureInfo.CompareInfo进行排序:
csharp
string[] arr = { "i", "I" };
Array.Sort(arr, StringComparer.CurrentCulture); // 按当前文化排序
-
对比:
Ordinal→ 按 Unicode 二进制值排序(不受文化影响)CurrentCulture→ 按系统文化排序InvariantCulture→ 固定不变文化排序(跨系统一致)
2.3 大小写转换
csharp
string s = "i";
Console.WriteLine(s.ToUpper(new CultureInfo("en-US"))); // I
Console.WriteLine(s.ToUpper(new CultureInfo("tr-TR"))); // İ
- 默认
ToUpper()使用CultureInfo.CurrentCulture - 指定 CultureInfo 可得到文化敏感的大写/小写映射
3️⃣ CompareInfo:底层实现
-
CultureInfo.CompareInfo提供了字符串比较的核心:csharpCultureInfo ci = new CultureInfo("tr-TR"); CompareInfo cmp = ci.CompareInfo; int result = cmp.Compare("i", "I", CompareOptions.IgnoreCase); -
CompareInfo 负责:
- 大小写映射(case mapping)
- 排序权重(collation)
- 文化特定规则(例如土耳其语、德语 ß、法语重音等)
4️⃣ 哈希值与 CultureInfo
-
StringComparer可以用来计算哈希:csharpStringComparer.CurrentCulture.GetHashCode("abc") -
Ordinal 系列 → 哈希基于字符 Unicode 值(跨文化稳定)
-
CurrentCulture → 哈希受文化规则影响(不同文化可能不同)
⚠️ 因此,如果需要跨文化稳定哈希,最好用
Ordinal。
5️⃣ 案例:土耳其语 vs 英语
csharp
string s1 = "i";
string s2 = "I";
CultureInfo en = new CultureInfo("en-US");
CultureInfo tr = new CultureInfo("tr-TR");
Console.WriteLine(s1.ToUpper(en)); // I
Console.WriteLine(s1.ToUpper(tr)); // İ
Console.WriteLine(string.Compare(s1, s2, true, en)); // 0
Console.WriteLine(string.Compare(s1, s2, true, tr)); // 0
- 英语和土耳其语的大写规则不同
- Compare、ToUpper、排序都会根据 CultureInfo 自动应用不同规则
6️⃣ 总结
-
string 本身不带文化信息,只是 Unicode 字符序列。
-
CultureInfo 影响:
- 排序:
CompareInfo.Compare/StringComparer.CurrentCulture - 比较:
string.Compare(strA, strB, culture)/CompareInfo - 大小写转换:
ToUpper(CultureInfo)/ToLower(CultureInfo) - 哈希:
StringComparer.CurrentCulture.GetHashCode(s)
- 排序:
-
Ordinal 系列操作不受文化影响,适合跨系统、跨文化的存储或比较。
-
InvariantCulture 提供跨文化一致规则。
-
底层依赖 CompareInfo(ICU 或 Windows NLS)实现文化敏感逻辑。