
后端【免费下载链接】reactiveThe Reactive Extensions for .NET项目地址https://gitcode.com/gh_mirrors/re/reactive点击查看免费下载本文是 Rx.NET 内置 Roslyn 分析器System.Reactive.Analyzers的规则使用指南。文章以仓库中的规则清单 AnalyzerReleases.Unshipped.md 为骨架结合 AddUiFrameworkPackageAnalyzer.cs 等源码实现系统讲解 RXNET0001 至 RXNET0004 四条诊断规则的触发场景、检测机制、消息内容与修复方法。读完本文你将能理解 Rx 7.0 包拆分背景下这些警告为何出现、如何精准识别因缺少 UI 框架专用 NuGet 包引用而导致的编译错误并掌握正确的升级修复路径。一、规则清单四条未发布Unshipped诊断规则System.Reactive.Analyzers项目采用 Roslyn 官方的 ReleaseTracking 机制管理诊断规则的发布状态规则清单保存在两个文件中AnalyzerReleases.Unshipped.md记录尚未随正式版本发布的新规则AnalyzerReleases.Shipped.md记录已经发布的规则当前内容为空仅有文件头注释说明 RXNET0001 至 RXNET0004 是该分析器的第一批新规则尚未随任何正式 NuGet 版本发布。Unshipped 清单中登记的四条规则如下Rule IDCategorySeverityNotesRXNET0001NuGetWarningAddUiFrameworkPackageAnalyzerWindows Forms 支持RXNET0002NuGetWarningAddUiFrameworkPackageAnalyzerWPF 支持RXNET0003NuGetWarningAddUiFrameworkPackageAnalyzerWindows Runtime 支持RXNET0004NuGetWarningAddUiFrameworkPackageAnalyzerUWP 支持四条规则全部由同一个分析器类 AddUiFrameworkPackageAnalyzer.cs 产生Category 均为NuGetSeverity 均为Warning并且默认启用isEnabledByDefault: true。它们分别对应四个 UI 框架专用包System.Reactive.WindowsForms、System.Reactive.Wpf、System.Reactive.WindowsRuntime与System.Reactive.Uwp。二、背景为什么 Rx 7.0 需要这样一个分析器要理解这四条规则的价值必须先了解 Rx 7.0 的包拆分决策。在 Rx 7 之前System.Reactive一个包承载了所有 UI 框架集成代码WPF 的DispatcherScheduler、Windows Forms 的ControlScheduler、WinRT 的CoreDispatcherScheduler与IEventPatternSourceTSender, TEventArgs、UWP 的DependencyObject调度支持等全部混在主包中。这带来一个严重问题任何目标框架为 Windows 特定 TFM如net8.0-windows10.0.19041且引用System.Reactive的应用无论是否使用 WPF/WinForms都会被强制引入Microsoft.Desktop.App框架依赖。对于自包含self-contained部署这一依赖会把部署体积从约 90MB 推高到 182MB即便配合裁剪也会带来约 47MB 的额外体积详见 ADR 0005Moving UI framework support out ofSystem.Reactive中的实测数据。Rx 7.0 的解决方案是UI 框架专用代码从System.Reactive的公共 APIref 程序集中移除但保留在运行时程序集lib中以维持二进制兼容需要继续使用这些类型和方法的代码必须显式引用新的 UI 框架专用包System.Reactive包本身不再强制引入Microsoft.Desktop.App依赖。正如 Rx.v7.md 所述这一改动属于源码级破坏性变更而非二进制级破坏性变更——升级后旧代码会突然出现难以理解的编译错误而分析器正是为了在这种情况下指引开发者找到正确的补救方向而存在。源码注释AddUiFrameworkPackageAnalyzer.cs 第 34-39 行明确说明了设计初衷升级到 Rx 7 时最可能遇到的摩擦点就是原本在 Rx 6 及更早版本中编译通过的 UI 框架代码突然报错且错误信息往往不会直接告诉开发者该引用哪个新包。三、分析器的运行机制只在编译出错时才介入与大多数持续扫描语法节点的分析器不同AddUiFrameworkPackageAnalyzer采用问题驱动的极简设计。从源码AddUiFrameworkPackageAnalyzer.cs可以看到其核心流程public override void Initialize(AnalysisContext context) { if (context is null) { throw new ArgumentNullException(nameof(context)); } context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterSemanticModelAction(AnalyzeSemanticModel); } private void AnalyzeSemanticModel(SemanticModelAnalysisContext context) { // 只遍历编译器已经报告的 Error 级别诊断 var d context.SemanticModel.GetDiagnostics(); foreach (var diag in d) { if (diag.Severity ! DiagnosticSeverity.Error) { continue; } var node diag.Location.SourceTree?.GetRoot().FindNode(diag.Location.SourceSpan); if (!UiFrameworkSpecificTypes.Check(context, node, diag)) { UiFrameworkSpecificExtensionMethods.CheckForExtensionMethods(context, node, diag); } } }关键设计决策注册的是RegisterSemanticModelAction而非语法节点回调。因为分析器只希望在已经存在编译错误的代码上运行正常情况下绝大多数编译是不需要介入的这样可以最大限度降低对构建性能的影响只处理Error级别的编译器诊断如 CS0234、CS0246、CS0103、CS1061、CS1503 等其余严重级别直接跳过分析器自身产生的诊断会被叠加在原始编译错误的位置上Diagnostic.Create(d, diag.Location, ...)即在报错处额外追加一条 RXNET 警告帮助开发者理解错误的根因项目启用并发执行EnableConcurrentExecution并跳过生成代码GeneratedCodeAnalysisFlags.None。需要特别注意的是该分析器不检测 VB.NET源码中以TODO: VB.NET?明确标注了这一点AddUiFrameworkPackageAnalyzer.cs 第 52 行并在[DiagnosticAnalyzer(LanguageNames.CSharp)]上限定仅作用于 C#。四、RXNET 规则与已移动类型的映射关系分析器维护了一张已移动类型清单UiFrameworkSpecificTypes.cs 第 65-75 行把旧包中的类型精确映射到对应的 RXNET 规则已移动类型所在命名空间泛型元数规则 ID目标包DispatcherSchedulerSystem.Reactive.Concurrency0RXNET0002System.Reactive.WpfControlSchedulerSystem.Reactive.Concurrency0RXNET0001System.Reactive.WindowsFormsCoreDispatcherSchedulerSystem.Reactive.Concurrency0RXNET0003System.Reactive.WindowsRuntimeWindowsObservableSystem.Reactive.Linq0RXNET0003System.Reactive.WindowsRuntimeIEventPatternSourceTSender, TEventArgsSystem.Reactive2RXNET0003System.Reactive.WindowsRuntime其中IEventPatternSource比较特殊它要求两个类型参数TSender、TEventArgs在诊断消息中会显示为全名IEventPatternSourceTSender, TEventArgs避免与主库中单参数的IEventPatternSourceTEventArgs混淆。源码注释指出这是一个awkward case——编译器可能误以为代码写错了类型参数个数而真实原因其实是IEventPatternSourceTSender, TEventArgs这个双参数类型已移入System.Reactive.WindowsRuntime包。五、RXNET 规则与已移动扩展方法的映射关系除类型外分析器还维护了一张更庞大的已移动扩展方法表UiFrameworkSpecificExtensionMethods.cs 第 27-90 行涵盖ObserveOn、SubscribeOn、ObserveOnDispatcher、SubscribeOnDispatcher、ObserveOnCoreDispatcher、SubscribeOnCoreDispatcher、ToObservable、ToObservableProgress、ToObservableMultiple、ToEventPattern等方法的数十个重载。典型映射关系RXNET0001Windows Forms目标包System.Reactive.WindowsFormsObserveOn(System.Windows.Forms.Control)SubscribeOn(System.Windows.Forms.Control)RXNET0002WPF目标包System.Reactive.WpfObserveOn(Dispatcher)/ObserveOn(Dispatcher, DispatcherPriority)ObserveOn(DispatcherObject)/ObserveOn(DispatcherObject, DispatcherPriority)SubscribeOn(Dispatcher)/SubscribeOn(Dispatcher, DispatcherPriority)等ObserveOnDispatcher()/SubscribeOnDispatcher()RXNET0003Windows Runtime目标包System.Reactive.WindowsRuntimeObserveOn(CoreDispatcher)/SubscribeOn(CoreDispatcher)等ObserveOnCoreDispatcher()/SubscribeOnCoreDispatcher()IAsyncAction/IAsyncOperation系列的ToObservable/ToObservableProgress/ToObservableMultipleIObservableEventPatternTSender, TEventArgs上的ToEventPattern()RXNET0004UWP目标包System.Reactive.UwpObserveOn(Windows.UI.Xaml.DependencyObject)/ObserveOn(DependencyObject, CoreDispatcherPriority)SubscribeOn(Windows.UI.Xaml.DependencyObject)系列设计上还特意不检测WindowsObservable.StandardSequenceOperators中四个带FuncTArg, TResult参数的SelectMany重载源码第 71-89 行的注释说明了原因因为表驱动的检测机制无法只凭参数类型FuncTArg, TResult判断返回类型是否为IAsyncOperationT强行检测会引入误报而实际项目中只使用这些重载、不使用其他 Windows Runtime 功能的场景极为罕见——一旦开发者添加包引用其他检测点会先于这些场景给出提示。六、消息内容警告文本与资源定义四条规则的标题、描述与消息格式全部定义在 Resources.resx 中通过LocalizableResourceString在分析器中加载保证多语言可本地化。以 RXNET0001 为例标题Rx.NET Windows Forms support is now in System.Reactive.WindowsForms消息格式The {0} {1} has moved. Add a reference to the System.Reactive.WindowsForms NuGet package.描述Add a reference to the System.Reactive.WindowsForms NuGet Package to continue using Rx.NET Windows Forms support.其中{0}是具体类型或方法名如ControlScheduler或ObserveOn(Control){1}是type或extension method占位符定义于 Resources.resx 中的TypeText与ExtensionMethodText。四条规则的消息模板结构完全一致仅目标包名不同RXNET0002 →System.Reactive.WpfRXNET0003 →System.Reactive.WindowsRuntimeRXNET0004 →System.Reactive.Uwp各规则的helpLinkUri统一指向https://github.com/dotnet/reactive即当前仓库的上游地址帮助开发者跳转查看项目主页与发布历史。七、防误报策略语法检测与语义验证的结合分析器的一个核心难点在于它必须在编译器无法解析类型的情况下工作因为要检测的正是已消失的类型。因此 UiFrameworkSpecificTypes.cs 采用几乎完全基于语法的策略同时通过语义模型验证来规避误报命名空间限定名匹配如果代码写出了完整的System.Reactive.Concurrency.DispatcherScheduler这类限定名直接按命名空间 简单名 泛型元数精确匹配非限定名匹配对只写简单名如DispatcherScheduler的情况先确认编译器确实无法解析该符号的类型ti.Type is null || ti.Type.TypeKind TypeKind.Error再检查相关命名空间是否通过using导入GetImportScopesImports检查。这样即使项目中碰巧存在一个同名但属于其他命名空间的类型也不会误报成员访问表达式匹配对System.Reactive.Concurrency.ControlScheduler.Current这类调用检查成员访问表达式的接收者文本是否就是目标命名空间并确认语义模型无法解析该成员类型扩展方法参数匹配扩展方法检测在 UiFrameworkSpecificExtensionMethods.cs 中通过表驱动实现需要满足方法名匹配、参数个数匹配、接收者类型是IObservableT通过 CodeAnalysisExtensions.cs 的IsIObservable等匹配器、所有参数类型已知且可继承自目标参数类型。源码注释第 19-30 行强调了两条设计红线避免误报和在不会产出诊断的场景避免开销——因为在开发者修复包引用之后该分析器仍会随每次编译错误被触发必须能快速判断无需干预并退出。八、测试验证行为即规格仓库为每条规则都配备了专门的测试类位于 System.Reactive.Analyzers.Test 目录WindowsFormsSchedulerNewPackageAnalyzerTests.cs验证ControlScheduler在完全限定名、using导入、嵌套命名空间、变量声明、字段/属性/返回类型等十余种写法下均能触发 RXNET0001WpfExtensionsNewPackageAnalyzerTests.cs验证ObserveOn/SubscribeOn系列重载触发 RXNET0002包括Dispatcher、DispatcherObject及其派生类型如System.Windows.Controls.Button作为DispatcherObject子类也能被识别等各种参数组合UapNewPackageAnalyzerTests.cs在 UAP 参考程序集环境下验证DependencyObject相关调用触发 RXNET0004另有 WindowsRuntimeSchedulerNewPackageAnalyzerTest.cs、WindowsRuntimeTypesNewPackageAnalyzerTest.cs、WindowsRuntimeExtensionsNewPackageAnalyzerTests.cs、WindowsFormsExtensionsNewPackageAnalyzerTests.cs 分别覆盖 RXNET0003 与 RXNET0001 的扩展方法场景。测试用例同时验证了分析器对底层编译器错误码如 CS0234、CS0246、CS0103、CS1061、CS1503的适配例如对于主库中已有同名方法的ObserveOn(Dispatcher)重载编译器会误判为参数类型错误CS1503诊断落在参数节点上而对于主库中不存在的ObserveOnDispatcher()编译器会报告方法不存在CS1061诊断落在调用节点上。分析器分别处理这两种情况详见 UiFrameworkSpecificExtensionMethods.cs 第 122-152 行。九、使用与修复从警告到正确配置9.1 如何启用分析器项目本身构建为netstandard2.0程序集依赖Microsoft.CodeAnalysis.CSharp4.12.0并启用了EnforceExtendedAnalyzerRules见 System.Reactive.Analyzers.csproj。当System.Reactive.Analyzers以 NuGet 分析器或随System.Reactive包以分析器方式进入项目后四条规则默认启用无需额外配置若需临时关闭可在.editorconfig或GlobalAnalyzerConfig中按规则 ID 设置严重级别例如dotnet_diagnostic.RXNET0002.severity none9.2 典型修复路径当编译器错误伴随 RXNET 警告出现时修复方式非常直接为项目添加对应 UI 框架专用包的引用。映射关系如下警告需要添加的包典型触发代码RXNET0001System.Reactive.WindowsFormsnew ControlScheduler(control)、obs.ObserveOn(control)RXNET0002System.Reactive.Wpfnew DispatcherScheduler(dispatcher)、obs.ObserveOnDispatcher()RXNET0003System.Reactive.WindowsRuntimenew CoreDispatcherScheduler(coreDispatcher)、asyncOperation.ToObservable()RXNET0004System.Reactive.Uwpobs.ObserveOn(dependencyObject)以 Windows Forms 项目为例升级到 Rx 7 后应在项目文件中加入ItemGroup PackageReference IncludeSystem.Reactive.WindowsForms Version7.0.0 / /ItemGroup此外还有一个连带配置点Rx 7 中System.Reactive不再自动带来Microsoft.Desktop.App框架引用如果应用本身确实依赖 WPF 或 Windows Forms 框架需要在项目文件中显式声明Rx.v7.md 第 19 行PropertyGroup UseWPFtrue/UseWPF !-- 或 UseWindowsFormstrue/UseWindowsForms -- /PropertyGroup9.3 一个已知的特殊场景WpfExtensionsNewPackageAnalyzerTests.cs 的文档注释描述了一个罕见的边界场景如果一个针对 Rx 6 编译的库公开了DispatcherScheduler类型的静态属性而应用升级到 Rx 7 后不添加System.Reactive.Wpf引用那么读取该属性的表达式会触发编译错误且仅添加 WPF 包也无法解决——因为运行时System.Reactive.dll中的DispatcherScheduler与System.Reactive.Wpf.dll中的同名类型被视为不同程序集中的不同类型。该场景的变通方案是用PackageDownload替换PackageReference并让编译器直接引用运行时程序集lib\net8.0-windows10.0.19401\System.Reactive.dll以重新获得那些被隐藏的 UI 类型。分析器目前刻意不为这种极少数场景产出诊断因为难以在一条消息里解释清楚测试注释也呼吁遇到此问题的开发者反馈给上游。十、小结System.Reactive.Analyzers的 RXNET0001 至 RXNET0004 四条规则是 Rx.NET 为化解 7.0 版本包拆分这一源码级破坏性变更而提供的贴心向导它只在实际编译错误出现时介入通过语法与语义结合的方式精准识别已移出System.Reactive公共 API 的类型与扩展方法并直接告诉开发者该引用哪个新的 UI 框架专用包。从 AnalyzerReleases.Unshipped.md 的规则登记到 Resources.resx 的消息文本再到 System.Reactive.Analyzers.Test 目录下覆盖各平台各写法的测试矩阵仓库完整展示了从问题背景见 ADR 0005 与 Rx.v7.md、规则设计到自动化验证的全链路。对于正从 Rx 6 及更早版本升级的开发者理解并善用这四条规则可以显著降低编译突然失败却不知所以然的升级摩擦。赞分享后端【免费下载链接】reactiveThe Reactive Extensions for .NET项目地址https://gitcode.com/gh_mirrors/re/reactive点击查看免费下载相关推荐downkyi过滤器规则导入向导分步导入复杂的规则集downkyi过滤器规则导入向导分步导入复杂的规则集 痛点直击复杂规则集导入的3大挑战 你是否遇到过这些情况从社区获取的高质量过滤器规则无法正确导入软件突破性三引擎架构DeeplxFile高性能文件翻译技术深度解析突破性三引擎架构DeeplxFile高性能文件翻译技术深度解析 在当今全球化协作环境中专业文档翻译面临着文件大小限制、格式兼容性差、API调用频率限制等核心桌面应用AI 应用postgres_lsp 安全规则解析unsupportedRegTypes 与 reg* 类型列导致的 pg_upgrade 升级隐患postgres_lsp 安全规则解析unsupportedRegTypes 与 reg 类型列导致的 pg_upgrade 升级隐患 本文基于 postgr开发工具数据库CLI上一篇如何快速上手ComfyUI-Custom-Scripts新手必看的10个入门技巧下一篇3小时精通Kanboard插件开发从零基础到发布全流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考