<p>u8后缀在C#中不可用;截至C# 12,"hello"u8会触发CS1056编译错误,因C#不支持类似C++20的UTF-8字符串字面量,其string类型固定为UTF-16编码。</p>

什么是 u8 后缀,它在 C# 中是否可用?
截至 C# 12(.NET 8),u8 后缀**不是合法的字符串字面量后缀**。你写 "hello"u8 会触发编译错误:CS1056: Unexpected character 'u' 或类似提示。C# 不支持像 C++20 那样用 u8"" 声明 UTF-8 编码的字符串字面量。
C# 中实际可用的字符串编码相关字面量后缀有哪些?
C# 目前只支持以下几种字符串后缀(全部作用于 string 类型):
-
@"":逐字字符串(verbatim string),禁用转义,但内容仍是 UTF-16 编码的string -
$"":内插字符串(interpolated string),运行时解析,底层仍是string -
$$"":原始内插字符串(C# 11+),语法更灵活,本质还是string
注意:所有这些都生成 string 实例,即 UTF-16 编码的字符序列,不是 UTF-8 字节序列。 C# 的 string 类型本身不承载编码信息,它固定为 UTF-16。
那怎么真正得到 UTF-8 字节常量?
如果你需要的是“UTF-8 编码后的字节序列”(比如用于 HTTP header、二进制协议、或传递给 native API),必须显式编码。没有编译期生成 byte[] 字面量的语法,但有几种实用方式:
- 用
Encoding.UTF8.GetBytes("text")在运行时转换 —— 简单,但每次调用有开销(可配合static readonly缓存) - 用
System.Text.Encoding.UTF8.GetBytes()+const字符串,例如:private static readonly byte[] Utf8Hello = Encoding.UTF8.GetBytes("Hello"); - C# 12 引入了
static abstract接口和源生成器,但目前仍无标准方式让编译器直接把"abc"u8编译成byte[]常量 - 若需零分配、零运行时编码,可手写
byte[]字面量(需查 UTF-8 编码表):private static readonly byte[] HelloUtf8 = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };—— 安全但不可读,且不支持非 ASCII 字符(如"café"需手动算出0xC3, 0xA9)
为什么 C# 不加 u8 后缀?
核心原因是设计定位不同:C# 的 string 是逻辑字符序列(基于 UTF-16),而 UTF-8 是传输/存储编码。语言层不鼓励把编码细节混入字符串类型。.NET 更倾向用 ReadOnlySpan<byte>、Utf8String(实验性,未进 BCL)、或 System.Text.Json 等专用类型处理 UTF-8 场景。真正需要高性能 UTF-8 操作时,应考虑 Utf8Parser / Utf8Formatter,而非试图让 string 承担编码职责。
容易忽略的一点是:即使未来加入 u8,它也只会是语法糖,最终仍要映射到 byte[] 或新类型(如 Utf8String),而不会改变 string 的语义 —— 这个边界在 .NET 设计里非常明确。










