解决字符串文本声明的错误和警告

C# 编译器在使用不正确的语法声明字符串文本时生成错误和警告,或在不支持的上下文中使用它们。 这些诊断有助于识别基本字符串文本、字符文本、原始字符串文本和 UTF-8 字符串文本的问题。

  • CS1009无法识别的转义序列。
  • CS1010常量中的换行符。
  • CS1011空字符文本。
  • CS1012字符文本中的字符过多。
  • CS1039未确定的字符串文本。
  • CS8996预处理器指令中不允许原始字符串文本。
  • CS8997未确定的原始字符串文本。
  • CS8998此原始字符串内容的起始引号不够。
  • CS8999行不以与原始字符串文本的结束行相同的空格开头。
  • CS9000原始字符串文本分隔符必须位于自己的行上。
  • CS9001仅在逐字内插字符串中允许多行原始字符串文本。
  • CS9002多行原始字符串文本必须至少包含一行内容。
  • CS9003行包含与预期不同的空格。
  • CS9004原始字符串文本的引号不足。
  • CS9005内插原始字符串文本的右大括号不够。
  • CS9006内插原始字符串文本的左大括号太多。
  • CS9007内插原始字符串文本的右大括号太多。
  • CS9008不允许使用“@”字符序列。
  • CS9009字符串必须以引号字符开头。
  • CS9026输入字符串无法转换为等效的 UTF-8 字节表示形式。
  • CS9047运算符不能应用于不是 UTF-8 字节表示的操作数。
  • CS9274无法在数据节中发出此字符串文本,因为它与另一个字符串文本发生 XXHash128 冲突。
  • CS9315程序使用的用户字符串的总长度超过允许的限制。添加字符串文本需要重启应用程序。

格式不正确的字符串文本

  • CS1009 - 无法识别的转义序列。
  • CS1010 - 常量中的换行符。
  • CS1011 - 空字符文本。
  • CS1012 - 字符文本中的字符过多。
  • CS1039 - 未确定的字符串文本。

若要更正这些错误,请应用以下技术:

  • 使用 C# 语言规范中定义的标准转义序列之一,例如 \n (newline)、(tab)、 \t\\ (反斜杠)或 \" (双引号)(CS1009)。 编译器无法识别不属于语言规范的转义序列,因此使用未定义的转义序列会导致此错误,因为编译器无法确定要表示的字符。
  • 添加右引号字符以完成字符串文本(CS1039)。 字符串文本必须同时具有左分隔符和结束分隔符,因此不确定的字符串会导致编译器将后续源代码视为字符串内容的一部分,从而导致分析错误。
  • 在字符文本中的单引号之间仅添加一个字符(CS1011CS1012)。 字符文本表示单个字符值,并且必须正好包含一个字符或有效的转义序列,因此空字符文本或包含多个字符的字符文本违反了类型的语言规则 char
  • 拆分跨多个源行的字符串文本,方法是用右引号结束每一行,并使用左引号开始下一行,并使用 + 运算符连接它们(CS1010)。 常规字符串文本不能包含实际的换行符,因为右引号必须出现在与左引号相同的行上,但可以通过串联或使用 逐字字符串原始字符串文本来实现多行字符串,从而允许嵌入换行符作为字符串内容的一部分。

有关详细信息,请参阅 字符串

格式不正确的原始字符串字面值

  • CS8996 - 预处理器指令中不允许原始字符串文本。
  • CS8997 - 未确定的原始字符串文本。
  • CS8998 - 此原始字符串内容的起始引号不足。
  • CS8999 - 行不以与原始字符串文本的结束行相同的空格开头。
  • CS9000 - 原始字符串的分隔符必须单独占一行。
  • CS9001 - 多行原始字符串文本仅在逐字内插字符串中允许使用。
  • CS9002 - 多行原始字符串文本必须至少包含一行内容。
  • CS9003 - 行包含与预期不同的空格。
  • CS9004 - 原始字符串文本的引号不足。
  • CS9005 - 内插原始字符串文本的右大括号不够。
  • CS9006 - 内插原始字符串文本的左大括号太多。
  • CS9007 - 内插原始字符串文本的右大括号太多。
  • CS9008 - 不允许使用“@”字符序列。
  • CS9009 - 字符串必须以引号字符开头。

若要更正这些错误,请应用以下技术:

  • 在预处理器指令中使用常规字符串字面量或逐字字符串字面量,而不是原始字符串字面量,例如#if#define#pragma (CS8996)。 预处理器指令在预处理阶段求值,即发生在词法分析之前,因此编译器无法识别这些上下文中的原始字符串字面量语法,因为原始字符串是在后续的词法分析阶段被标识的。
  • 添加一个与起始分隔符匹配的结束分隔符以完成原始字符串常量(CS8997CS9004)。 原始字符串文本语法要求开始和结束分隔符包含相同数量的连续双引号字符(至少三个),因此缺失或不匹配的结束分隔符可防止编译器确定字符串内容结束的位置。
  • 将多行原始字符串文本的开始和结束分隔符放在自己的行上,这些行上没有其他内容(CS9000)。 多行原始字符串格式规则要求分隔符占用专用行来为字符串内容建立明确的边界,并启用从所有内容行中删除常见前导缩进的空格修整行为。
  • 在多行原始字符串文本(CS9002)的开始和结束分隔符之间至少添加一行内容。 语言规范要求多行原始字符串包含实际内容,因为空多行原始字符串没有用途,并可能指示不完整的代码,而单行原始字符串(同一行中的分隔符)可以为空,并且是空字符串值的相应语法。
  • 调整原始字符串内容行的缩进,以匹配或超过结束分隔符行(CS8999,CS9003)的缩进。 原始字符串文本的 空格处理规则 以结束分隔符的前导空格为基准,剪裁所有内容行的共同缩进。因此,缩进少于结束分隔符的内容行违反了此剪裁算法,并表明格式不正确。
  • 增加原始字符串分隔符中的双引号字符数,以超过内容中任何连续的引号字符数(CS8998)。 分隔符必须包含的连续引号必须多于字符串内容中的任何序列,以便编译器可以明确区分属于内容的引号字符和标记字符串末尾的分隔符序列。
  • 对于内插的原始字符串字面量,请确保开头的美元符号数($)与您需要作为字面内容的连续左大括号或右大括号数匹配(CS9005CS9006CS9007)。 插值原始字符串语法使用美元符号计数来确定大括号转义序列的长度,因此$$"""需要{{插值孔,并允许单个{字符作为内容。当大括号序列不匹配时,这意味着插值语法不正确或内容需要不同数量的美元符号。
  • @从原始字符串文本中删除前缀,并仅使用引号字符分隔符(CS9008,CS9009)。 原始字符串字面量是 C# 11 中引入的一种独特语法,不使用 @ 逐字字符串前缀。语言规范不允许将逐字语法与原始字符串分隔符 @ 组合,因为原始字符串已经支持多行内容,并且不需要转义序列。

注释

CS9001 不再在 C# 的当前版本中生成。 多行原始字符串文本现在支持内插,而无需逐字格式。

有关详细信息,请参阅 原始字符串文本

UTF-8 字符串字面量

  • CS9026 - 输入字符串无法转换为等效的 UTF-8 字节表示形式。
  • CS9047 - 不能将运算符应用于不是 UTF-8 字节表示的操作数。

若要更正这些错误,请应用以下技术:

  • 从字符串文本中删除不能在 UTF-8 u8 中编码的字符或转义序列(CS9026)。 UTF-8 编码规范支持完整的 Unicode 字符集,但需要有效的 Unicode 标量值,因此代理码点(在 U+D800 到 U+DFFF 范围内的值)不能直接出现在 UTF-8 字符串中,因为它们保留用于 UTF-16 代理项对编码,而不是表示独立字符,并且尝试将它们编码为 UTF-8 将生成无效的字节序列。
  • 在连接 UTF-8 字符串(u8)时,请确保加法运算符的两个作数都是 UTF-8 字符串文本(标有后缀)。 编译器在编译时为连接 UTF-8 字符串文本 提供特殊支持, 它生成 ReadOnlySpan<byte> 表示串联的 UTF-8 字节序列的值,但不支持将 UTF-8 字符串与常规 string 值或其他类型混合,因为类型系统无法确定是生成字节范围还是文本字符串,并且基础表示形式(UTF-8 字节与 UTF-16 字符)基本不兼容。

有关详细信息,请参阅 UTF-8 字符串文本

数据部分中的文本字符串

  • CS9274无法在数据节中发出此字符串文本,因为它与另一个字符串文本发生 XXHash128 冲突。
  • CS9315程序使用的用户字符串的总长度超过允许的限制。添加字符串文本需要重启应用程序。

若要修复这些问题,请尝试以下技术:

  • 遇到哈希冲突(CS9274)时,禁用应用程序的实验数据节字符串文本功能。 此错误指示两个不同的字符串文本生成了相同的 XXHash128 值,这可以防止优化正常工作,因此应删除启用此实验行为的功能标志。
  • 启用数据节功能(CS9315)后,在调试会话中修改字符串文本后重启应用程序。 热重载基础结构无法更新存储在数据段中的字符串文本,因为它们以一种运行时无法修改的特殊格式嵌入,因此继续使用旧字符串值执行会产生不正确的行为。