通过


与源生成器和侦听器关联的错误和警告

在编译期间加载源生成器或侦听器时,将生成以下错误:

  • CS9137未启用“拦截器”实验功能。请将 <Features>InterceptorsPreview</Features> 添加到您的项目中。
  • CS9138方法不能用作拦截器,因为它或其包含类型具有类型参数。
  • CS9139无法截获:编译不包含包含路径的文件。
  • CS9140无法截获:编译不包含包含路径的文件。是否要使用其他路径?
  • CS9141提供的行号和字符号并非指向一个可拦截的方法名称,而是指向一个标记。
  • CS9142给定文件包含 n 的行数少于提供的行号 m
  • CS9143给定行长 c ,小于提供的字符号 n
  • CS9144无法通过侦听器截获M方法V,因为签名不匹配。
  • CS9145无法截获:路径未映射。预期的映射路径。
  • CS9146拦截器方法必须是普通成员方法。
  • CS9147提供的行号和字符号不指向令牌的起始位置。您是否打算使用行 n 和字符 c
  • CS9148侦听器必须具有 this 参数匹配参数。
  • CS9149拦截器不得具有 this 参数,因为方法没有 this 参数。
  • CS9150侦听器不能有 null 文件路径。
  • CS9151无法截获可能的方法名称 M ,因为它未调用。
  • CS9152由于编译中的多个文件具有此路径,因此无法截获文件中的调用。
  • CS9153指明的调用多次被拦截。
  • CS9155无法拦截调用M,因为它在V中不可访问。
  • CS9156由于“作用域”修饰符或M属性存在差异,无法截获对V[UnscopedRef]调用。
  • CS9157提供的 InterceptsLocationAttribute 行号和字符数必须为正数。
  • CS9160无法截获 nameof 运算符。
  • CS9161无法标记 UnmanagedCallersOnlyAttribute拦截器。
  • CS9177拦截器必须是非泛型或具有匹配的参数个数。
  • CS9178方法必须是非泛型方法才能匹配
  • CS9206无法在全局命名空间中声明侦听器。
  • CS9207无法截获,因为方法不是调用普通成员方法。
  • CS9231InterceptsLocationAttribute 的数据参数的格式不正确。
  • CS9232不支持拦截器格式的版本‘version’。支持的最新版本为“1”。
  • CS9233无法拦截文件 'file' 中的函数调用,因为在编译过程中的其他地方有重复。
  • CS9234无法截获文件“file”中的调用,因为编译中找不到匹配的文件。
  • CS9235InterceptsLocationAttribute 的数据参数引用文件“file”中的无效位置。

在编译期间加载源生成器或侦听器时,将生成以下警告:

  • CS8784生成器“”YourSourceGeneratorName无法初始化。它不会导致输出和编译错误,因此可能会发生。
  • CS8785生成器“”YourSourceGeneratorName无法生成源。它不会导致输出和编译错误,因此可能会发生。
  • CS9057无法使用分析器程序集,因为它引用的编译器版本比当前正在运行的版本更新。
  • CS9067分析器引用被多次指定。
  • CS9154使用拦截器 M 拦截调用 V,但签名不匹配。
  • CS9158返回类型中引用类型的可空性与可拦截的函数不匹配。
  • CS9159参数类型中的引用类型的可空性与可拦截的方法不匹配。
  • CS9270不支持“InterceptsLocationAttribute(string, int, int)”。改为移动到基于“InterceptableLocation”的这些属性的生成。 ()https://github.com/dotnet/roslyn/issues/72133)

这些错误和警告遵循以下主题:

拦截器是实验性的

  • CS9137未启用“拦截器”实验性功能。将 <Features>InterceptorsPreview</Features> 添加到项目中。

若要使用拦截器,请将<Features>InterceptorsPreview</Features>元素添加到<PropertyGroup>部分的CS9137项目文件中,因为拦截器是默认情况下未启用的实验性功能。 此显式选择加入是必需的,因为拦截器功能在未来版本中可能会发生重大更改或删除,编译器需要确认你先了解风险,然后再允许其使用。 有关拦截器及其功能的详细信息,请参阅 C# 12 功能文档中的 侦听器

签名不匹配

以下错误和警告表示侦听器方法与可截获方法不匹配。

  • CS9144无法通过侦听器截获M方法V,因为签名不匹配。
  • CS9148this
  • CS9149拦截器不能有this参数,因为方法没有this参数。
  • CS9155无法截获调用,因为 MV 中不可访问。
  • CS9156由于“作用域”修饰符或M属性存在差异,无法拦截对V[UnscopedRef]的调用。
  • CS9177]: 拦截器必须是非泛型或具有匹配的参数个数。
  • CS9178方法必须是非泛型方法才能匹配

此外,以下警告指示侦听器签名和可截获方法的签名不匹配:

  • CS9154使用拦截器M截获V的调用,但签名不匹配。
  • CS9158返回类型中引用类型的可为 Null 的特性与可被拦截的方法不匹配。
  • CS9159参数的引用类型的可空性与可拦截方法不匹配。
  • CS9270不支持“InterceptsLocationAttribute(string, int, int)”。改为移动到基于“InterceptableLocation”的这些属性的生成。 ()https://github.com/dotnet/roslyn/issues/72133)

若要更正这些问题,请确保侦听器方法与可拦截方法的签名和访问要求匹配:

  • 确保侦听器方法签名与可拦截方法完全匹配(CS9144,CS9154)。 参数类型、修饰符、顺序和返回类型必须相同。 查看方法声明并对齐其签名。
  • this当可截获方法为实例方法(CS9148)时,将参数添加到侦听器,或者在可拦截方法为静态(this)时删除该参数。 实例拦截器需要 this 声明类型的参数,但静态拦截器不需要。
  • 在可访问可拦截方法的位置(CS9155)中声明拦截器。 如果可截获方法为 internal,则侦听器必须位于同一程序集中。 private如果是,则侦听器必须位于同一类型或嵌套类型中。
  • 匹配相应参数上的scoped修饰符和[UnscopedRef]属性refCS9156)。 ref侦听器中的每个参数都必须具有与可拦截方法中相应参数相同的生存期批注,以确保内存安全。
  • 确保这两种方法都具有匹配的泛型元数(CS9177CS9178)。 如果可拦截方法是非泛型方法,则侦听器也必须是非泛型方法。 如果可截获方法具有类型参数,则侦听器必须具有与兼容约束相同的类型参数数。
  • 匹配返回类型(CS9158)和参数类型(CS9159)中的可为 null 性批注。 在项目中启用可为空的引用类型,并确保拦截器的可空性批注与可截方法完全匹配,以保持类型安全性。
  • 使用基于更新的InterceptableLocation生成来替代已弃用的InterceptsLocationAttribute构造函数(string, int, int)CS9270)。 较新的格式提供更好的工具支持和编译时验证。 有关迁移指南,请参阅 GitHub 问题

映射不正确

拦截器需要源映射来映射可拦截方法和拦截器方法。 以下错误表示映射出现问题:

  • CS9139无法截获:编译不包含包含路径的文件。
  • CS9140无法截获:编译不包含包含路径的文件。是否要使用其他路径?
  • CS9141提供的行号和字符号不对应可拦截的方法名称,而是对应一个令牌。
  • CS9142给定文件包含 n 的行数少于提供的行号 m
  • CS9143给定行长 c ,小于提供的字符号 n
  • CS9145无法截获:路径未被映射。预期路径已映射。
  • CS9147提供的行号和字符号没有指向令牌的开始。您是否打算使用行 n 和字符 c
  • CS9150侦听器不能有 null 文件路径。
  • CS9157提供的 InterceptsLocationAttribute 行号和字符数必须为正数。

若要更正映射错误,请确保 InterceptsLocationAttribute 包含有效的文件路径和准确的位置信息:

  • 验证文件路径是否与编译中的文件完全匹配(CS9139CS9140)。 使用项目里显示的确切路径,包括正确的大小写和目录分隔符。 如果编译器建议备用路径,请更新属性以使用该路径。
  • 使用转换文件路径的源生成器(CS9145)时,请使用映射的文件路径。 源生成器通常重新映射生成的文件的路径,并且必须使用编译器识别的映射路径,而不是原始源路径。
  • 确保文件路径不是null位于您的InterceptsLocationAttributeCS9150)中。 每个截获都必须指定一个有效的非 null 文件路径,用于标识包含要截获的调用的源文件。
  • 提供以 1 为基准的正行号和字符号(CS9157)。 行号和字符位置必须从 1 开始,而不是 0。 验证源生成器在计算位置时使用基于 1 的索引。
  • 指向方法名称标识的确切起点(CS9141CS9147)。 行号和字符号必须标识调用中方法名称的第一个字符,而不是空格、运算符或其他标记。 如果编译器建议替代坐标,请使用这些坐标来定位正确的令牌起始。
  • 保留在文件的边界内(CS9142CS9143)。 验证行号不超过总行数,字符编号不超过行长度。 如果自生成属性后源文件已更改,则重新计算位置。

拦截器声明不正确

以下错误表明拦截器声明中的问题,包括 InterceptsLocationAttribute 格式问题或违反拦截器规则的情况。

  • CS9138方法不能用作拦截器,因为它或其包含类型具有类型参数。
  • CS9146拦截器方法必须是普通成员方法。
  • CS9151无法截获可能的方法名称 M ,因为它未调用。
  • CS9152由于编译中的多个文件具有此路径,因此无法截获文件中的调用。
  • CS9153指示的通话多次被截获。
  • CS9160无法截获 nameof 运算符。
  • CS9161无法标记 UnmanagedCallersOnlyAttribute拦截器。
  • CS9206无法在全局命名空间中声明侦听器。
  • CS9207无法截获,因为方法不是调用普通成员方法。
  • CS9231InterceptsLocationAttribute 的数据参数的格式不正确。
  • CS9232不支持截取器格式的版本“version”。支持的最新版本为“1”。
  • CS9233无法拦截文件“file”中的调用,因为它在编译的其他位置已被重复。
  • CS9234无法截获文件“file”中的调用,因为编译中找不到匹配的文件。
  • CS9235InterceptsLocationAttribute 的数据参数引用文件“file”中的无效位置。

若要更正拦截器声明错误,请遵循以下规则,以获取有效的拦截器声明和 InterceptsLocationAttribute 使用方法:

  • InterceptsLocationAttribute正确格式化数据参数(CS9231)。 该属性需要对文件路径和位置信息进行编码的结构化数据。 确保源生成器以与当前拦截器规范匹配的预期格式生成数据。
  • 在 (InterceptsLocationAttribute) 中使用版本“1”,因为它是最新的受支持版本。 将源生成器更新为输出版本 1 格式属性,而不是不支持的版本号。
  • 确保编译中的唯一文件路径(CS9233CS9234)。 当编译包含重复的文件路径时,请重命名或重新组织文件以使每个路径唯一。 验证属性中的文件路径是否与编译中实际包含的文件匹配。
  • 验证位置数据指向有效的代码位置(CS9235)。 行号和字符号必须引用指定文件中的有效拦截点。 如果源文件已更改或位置超出文件边界,则重新生成属性。
  • 在非泛型类型(CS9138)中声明非泛型拦截器方法。 拦截器不能在方法本身或其包含类型上具有类型参数。 如果需要截获泛型方法,请创建一个适用于特定构造类型的非泛型侦听器。
  • 将拦截器设为普通成员函数(CS9146)。 侦听器不能是运算符、构造函数、终结器、属性或索引器。 将拦截器声明为常规静态或实例方法。
  • 截获实际方法调用,而不是表达式(CS9151CS9207)。 只能截获对正在调用的普通成员函数的操作。 不能截获那些未被调用的情况下引用的方法组、委托或方法。 确保可拦截的代码位置标识真正的方法调用。
  • 删除重复的拦截尝试(CS9153)。 每个方法调用只能拦截一次。 如果多个 InterceptsLocationAttribute 实例以相同的调用为目标,请删除除一个实例在内的所有实例来解决歧义。
  • 不要截获 nameof 运算符(CS9160)。 运算符 nameof 不会在运行时调用方法,因此无法截获。 仅截获在运行时执行的实际方法调用。
  • 从拦截器中删除 UnmanagedCallersOnlyAttributeCS9161)。 拦截器必须可以从托管代码调用,并且不能标记为 UnmanagedCallersOnlyAttribute。 从侦听器方法声明中删除属性。
  • 声明命名空间中的侦听器(CS9206)。 侦听器不能在全局命名空间中声明,并且必须包含在至少一个命名空间声明中。 将拦截器类包装在命名空间中。
  • 解析编译级别的重复文件路径(CS9152)。 当多个文件在编译中共享同一路径时,编译器无法确定要截获的文件。 确保构建配置生成唯一的文件路径,或对源文件采用不同的组织策略。

分析器兼容性

以下警告指示分析器或源生成器程序集出现问题:

  • CS9057无法使用分析器程序集,因为它引用的编译器版本比当前正在运行的版本更新。
  • CS9067分析器引用被多次定义。

当分析器程序集出现兼容性问题时,会出现以下警告:

  • 当分析器程序集引用的 Roslyn 编译器版本高于当前运行的编译器时,将生成 CS9057。 这会阻止分析器加载,因为它可能依赖于当前编译器版本中不可用的 API 或行为。 若要解决此问题,请升级编译器/SDK 以满足分析器的要求,或使用与当前编译器版本兼容的分析器版本。
  • CS9067 会在项目中多次引用同一分析器程序集时发出警告。 当分析器通过多个路径或包引用包含时,通常会发生这种情况。 虽然不是错误,但重复引用可能会影响生成性能,并可能导致意外行为。 删除重复引用以解决此警告。