char类型在c#中是utf-16编码的单个unicode代码单元(2字节,u+0000–u+ffff),bmp外字符需代理对;支持四种等价初始化方式;isxxx方法基于unicode数据库判断字符类别;大小写转换分文化敏感与不变文化两种;遍历字符串时length返回char数而非真实字符数。

char 类型在 C# 中不是 ASCII,而是 UTF-16 编码的单个 Unicode 代码单元,占 16 位(2 字节),取值范围是 U+0000 到 U+FFFF。它能表示基本多文种平面(BMP)内的所有字符,但对超出 BMP 的字符(如某些 emoji 或古文字),需用代理对(surrogate pair)两个 char 组合表示——这点直接影响字符串长度、索引访问和遍历逻辑。
char 的四种初始化方式与编码本质
同一个字符可通过不同编码形式赋值,本质都是得到相同的 UTF-16 码元:
- 字符字面量:
char c1 = 'A';—— 最直观,仅限可打印、无转义的单字符 - Unicode 转义:
char c2 = '\u0041';—— 四位十六进制,对应 U+0041(即 'A') - 十六进制转义:
char c3 = '\x0041';—— 同样是 U+0041,位数不固定,但建议补零对齐 - 整数强制转换:
char c4 = (char)65;—— 直接使用 UTF-16 码点值,适合动态构造
这四种写法在编译后完全等价,运行时都生成相同内存值。注意:不能用 \U(大写 U)或八进制(如 \065),C# 不支持。
判断字符类别的核心方法(IsXXX)
System.Char 提供一系列静态布尔方法,用于安全识别字符语义类别,比手动查 ASCII 码或硬编码更可靠、国际化友好:
-
Char.IsDigit('5')→ true(仅限 0–9 阿拉伯数字) -
Char.IsNumber('Ⅷ')→ true(含罗马数字、上标数字等广义数字) -
Char.IsLetter('α')→ true(支持希腊、西里尔、汉字部首等所有 Unicode 字母) -
Char.IsWhiteSpace('\u3000')→ true(中文全角空格,U+3000) -
Char.IsPunctuation(',')→ true(中文顿号,非英文逗号) -
Char.IsSurrogate('\uD83D')→ true(高代理项,常见于 emoji 开头)
这些方法内部基于 Unicode 字符数据库分类,无需关心区域设置,适用于多语言文本处理场景。
大小写转换与文化敏感性
大小写操作看似简单,但实际涉及语言规则。C# 提供两套 API:
-
Char.ToLower('İ')和Char.ToUpper('i')—— 依赖当前线程文化(Thread.CurrentThread.CurrentCulture),土耳其语中 'I'→'ı'、'i'→'İ' 就会体现差异 -
Char.ToLowerInvariant('İ')和Char.ToUpperInvariant('i')—— 使用不变文化(invariant culture),行为稳定、可预测,推荐用于标识符处理、配置解析等非 UI 场景
例如解析 HTTP 头名或 JSON 键名时,应优先用 Invariant 版本,避免因服务器区域设置不同导致逻辑错误。
char 与字符串遍历的常见陷阱
字符串是 char 序列,但 string.Length 返回的是 char 个数,不是真实 Unicode 字符数:
-
"??".Length == 4—— 实际是一个 emoji(ZWNJ 连接的代理对 + 修饰符),占 4 个 char - 直接用
for (int i = 0; i 会把代理对拆开,可能输出乱码或异常 - 正确做法:用
StringInfo.GetTextElementEnumerator(s)或 .NET 5+ 的s.EnumerateRunes()按 Unicode 标量值(Rune)遍历
若仅做简单 ASCII 处理且确定输入无 emoji/BMP 外字符,char 索引仍高效;否则务必升级到 Rune 级别操作。











