深入讲解 C# 中 string 如何支持 CultureInfo

1️⃣ 基础概念:string 与 CultureInfo

  • string 是 不可变的 Unicode 字符序列(UTF-16)。

  • string 本身不包含文化信息,只是字符集合。

  • CultureInfo 是 .NET 中表示"文化/地区/语言环境"的类,例如:

    csharp 复制代码
    var 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 提供了字符串比较的核心:

    csharp 复制代码
    CultureInfo ci = new CultureInfo("tr-TR");
    CompareInfo cmp = ci.CompareInfo;
    int result = cmp.Compare("i", "I", CompareOptions.IgnoreCase);
  • CompareInfo 负责:

    1. 大小写映射(case mapping)
    2. 排序权重(collation)
    3. 文化特定规则(例如土耳其语、德语 ß、法语重音等)

4️⃣ 哈希值与 CultureInfo

  • StringComparer 可以用来计算哈希:

    csharp 复制代码
    StringComparer.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️⃣ 总结

  1. string 本身不带文化信息,只是 Unicode 字符序列。

  2. CultureInfo 影响:

    • 排序:CompareInfo.Compare / StringComparer.CurrentCulture
    • 比较:string.Compare(strA, strB, culture) / CompareInfo
    • 大小写转换:ToUpper(CultureInfo) / ToLower(CultureInfo)
    • 哈希:StringComparer.CurrentCulture.GetHashCode(s)
  3. Ordinal 系列操作不受文化影响,适合跨系统、跨文化的存储或比较。

  4. InvariantCulture 提供跨文化一致规则。

  5. 底层依赖 CompareInfo(ICU 或 Windows NLS)实现文化敏感逻辑。

相关推荐
坤坤子吖1 天前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
一晌小贪欢1 天前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
xiaoye-duck1 天前
《C++ 项目:手写大模型接入 SDK》LLMManager架构设计与实现
开发语言·网络·c++·语言模型
一条大祥脚1 天前
CuTe 与 CuTe DSL:从 C++ 模板元编程到 Python DSL 的 GPU 编程演进
开发语言·c++·python·cutlass·cute·cute dsl
FRing031 天前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
旖旎夜光1 天前
【C++ 基础入门】C++ 多态(上):虚函数、重写、override/final 与抽象类
开发语言·c++·笔记·学习
starzy19901 天前
深入理解Scala嵌套函数:作用域封装之道
开发语言·scala
Sakura_j_h_1 天前
从零写一个 MCP stdio Server:用 Python 校验博客文章格式
开发语言·python·自动化·ai工具·mcp·json-rpc
白杨尚青1 天前
C++进阶篇(五):红黑树——四条规则、三种插入情况与旋转变色
开发语言·数据结构·c++·stl·红黑树·平衡二叉树
.道阻且长.1 天前
Linux基本开发工具:gdb和cgdb的使用
linux·运维·服务器·开发语言