预览版 API

.NET 平台以认真对待兼容性而自豪。 因此,库生态系统倾向于避免进行中断性变更,尤其是在 API 方面。

尽管如此,在设计 API 时,收集用户的反馈并在必要时根据该反馈更改 API,这一点很重要。 为了避免感到意外,用户有必要了解哪些 API 会被视为稳定,而哪些 API 仍在积极开发中并可能会发生变化。

有多种方法可将 API 以预览形式表示:

本文介绍如何在这些选项之间进行选择,以及每个选项的工作原理。

.NET 运行时预览版

除了具有上线许可证的候选版本 (RC) 外,不支持 .NET 运行时和 SDK 的预览版本。

因此,作为 .NET 预览版的一部分添加的任何 API 都被视为可能根据预览版收到的反馈进行更改。 若要使用 .NET 运行时预览版,需要显式面向较新的框架版本。 通过这样做,你隐式地表示同意使用可能会更改的 API。

与发行版 NuGet 包

NuGet 包可以是稳定的,也可标记为与发行版(即,包具有预发行版前缀)。 例如,System.Text.Json 9.0.0-preview.2.24128.5 具有预发行版前缀 preview.2.24128.5

包作者通常不支持预发行版包,并将它们用作收集早期采用者的反馈的方法。

通过 CLI 或 UI 安装包时,通常必须显式指示是否要安装预发行版,再次隐式表示同意使用可能会更改的 API。

RequiresPreviewFeaturesAttribute

由于 .NET 6,平台包含 RequiresPreviewFeaturesAttribute 特性。

此特性用于需要跨堆栈的预览行为的 API,包括运行时、C# 编译器和库。 使用标有此特性的 API 时,除非项目设置 <EnablePreviewFeatures>true</EnablePreviewFeatures>,否则会收到生成错误。 如果将该属性设置为 true,还会设置 <LangVersion>Preview</LangVersion>,从而允许使用预览语言功能。

.NET 团队使用 .NET 6 中的 RequiresPreviewFeaturesAttribute 特性来测试泛型数学,因为它需要当时处于预览状态的静态接口成员。

ExperimentalAttribute

.NET 8 添加了 ExperimentalAttribute,它不需要任何运行时或语言预览功能,并且只是指示给定的 API 尚不稳定。

针对试验性 API 生成时,编译器将生成错误。 标记为试验性的每个功能都自带单独的诊断 ID。 若要表示同意使用它们,请取消特定诊断。 可通过任何取消诊断的方式来做到这一点,但推荐的方法是将诊断添加到项目的 <NoWarn> 属性。

由于每个试验性功能都有单独的 ID,因此同意使用一个试验性功能并不同意使用另一个功能。

在选项之间进行选择

库开发人员应仅使用预发行版 NuGet 包或标记有 [Experimental] 的 API:

  • 对于在包的预发行版中引入的新 API,无需执行任何操作;包已经表示了预览质量。

  • 如果要提供包含某些预览质量 API 的稳定包,应使用 [Experimental] 标记这些 API。 确保使用自己的诊断 ID,并使其特定于这些功能。 如果你有多个独立功能,请考虑使用多个 ID。

[RequiresPreviewFeatures] 特性仅适用于 .NET 平台本身的组件。 即使这样,它也仅用于需要运行时和语言预览功能的 API。 如果它只是处于预览状态的 API,则 .NET 平台使用 [Experimental] 特性。

此规则的例外情况是,如果你正在构建稳定的库,并且想要公开某些功能,而这些功能又依赖于运行时或语言预览行为。 在这种情况下,应为该功能的入口点使用 [RequiresPreviewFeatures]。 但是,需要考虑到此类 API 的用户也必须启用预览功能,这会将它们暴露给所有运行时、库和语言预览行为。