在 Visual Studio 2019 高级构建设置中,C# 8 似乎不适用于 .NET Framework 项目,仅(如下图所示)适用于 .NET Core 3.0 项目:
C# 8 是否支持 .NET 框架?
是的,C# 8 可以与 Visual Studio 2019 中的 .NET Framework 和其他早于 .NET Core 3.0/.NET Standard 2.1 的目标一起使用(如果您安装了 NuGet 包,则可以使用旧版本的 Visual Studio )。
唯一需要的是8.0在 csproj 文件中设置语言版本。您也可以在Directory.Build.props中执行此操作,以将其应用于解决方案中的所有项目。请阅读下文,了解如何在 Visual Studio 2019 版本 16.3 及更高版本中执行此操作。
8.0
大多数(但不是全部)功能都适用于目标框架。
以下功能仅是语法更改;无论框架如何,它们都可以工作:
这些需要 .NET Framework 中没有的新类型。它们只能与“polyfill”NuGet 包或代码文件一起使用:
默认接口成员不会在 .NET Framework 下编译并且永远不会工作,因为它们需要在 CLR 中进行运行时更改。.NET CLR 现在已冻结,因为 .NET Core 现在是前进的方向。
有关什么起作用和不起作用以及可能的 polyfill 的更多信息,请参阅 Stuart Lang 的文章 C# 8.0 and .NET Standard 2.0 - Doing Unsupported Things。
以下 C# 项目以 .NET Framework 4.8 为目标并使用 C# 8 可为空的引用类型在 Visual Studio 16.2.0 中编译。我通过选择 .NET 标准类库模板创建它,然后将其编辑为以 .NET Framework 为目标:
.csproj:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>net48</TargetFrameworks> <LangVersion>8.0</LangVersion> <Nullable>enable</Nullable> </PropertyGroup> </Project>
。CS:
namespace ClassLibrary1 { public class Class1 { public string? NullableString { get; set; } } }
然后我尝试了一个 .NET Framework 4.5.2 WinForms 项目,使用旧.csproj格式,并添加了相同的可为空的引用类型属性。我将 Visual Studio 高级构建设置对话框(在 16.3 中禁用)中的语言类型更改为latest并保存了项目。当然,在这一点上它没有建立。我在文本编辑器中打开项目文件并在构建配置中更改latest为:preview``PropertyGroup
.csproj
latest
preview``PropertyGroup
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>然后,我通过添加到 main 来启用对可为空的引用类型的支持PropertyGroup:
<Nullable>enable</Nullable>
PropertyGroup
<PropertyGroup> <Nullable>enable</Nullable>
我重新加载了项目,它构建了。
Visual Studio 2019 版本 16.3 的 RTM 版本(C# 8.0 的启动版本)发生了重大变化:语言选择下拉菜单已被禁用:
微软这样做的理由是:
展望未来,……每个框架的每个版本都将有一个受支持的默认版本,我们不会支持任意版本。为了反映支持方面的这一变化,此提交永久禁用语言版本组合框,并添加指向解释该更改的文档的链接。
打开的文档是C# language versioning。这仅将 C# 8.0 列为 .NET Core 3.x 的默认语言。它还确认 每个框架的每个版本都将有一个受支持的默认版本 ,并且不再依赖该语言的框架不可知论。
通过编辑 .csproj 文件,仍然可以将 .NET Framework 项目的语言版本强制为 8。
首次编写此答案时,C# 8 处于预览阶段,涉及大量侦探工作。 我将这些信息留给后代。如果您不需要了解所有血腥细节,请随意跳过它。
C# 语言历来大多是框架中立的——即能够编译旧版本的框架——尽管某些特性需要新的类型或 CLR 支持。
大多数 C# 爱好者都会阅读 Mads Torgersen 的博客文Building C#8.0,其中解释了 C# 8 的某些特性具有平台依赖性:
异步流、索引器和范围都依赖于将成为 .NET Standard 2.1 一部分的新框架类型...... .NET Core 3.0 以及 Xamarin、Unity 和 Mono 都将实现 .NET Standard 2.1,但 .NET Framework 4.8 将不是。这意味着使用这些功能所需的类型将在 .NET Framework 4.8 上可用。
这看起来有点像C# 7 中引入的值元组ValueTuple。该功能需要新类型 -结构 - 在低于 4.7 的 NET Framework 版本或低于 2.0 的 .NET Standard 中不可用。 但是 ,C# 7 仍然可以在旧版本的 .NET 中使用,或者没有值元组,或者通过安装System.ValueTuple Nuget 包来使用它们。Visual Studio 明白这一点,一切都很好。
ValueTuple
然而,Mads 也写道:
因此,仅在实现 .NET Standard 2.1 的平台上支持使用 C# 8.0。
…如果属实,将排除在 任何 版本的 .NET Framework 中使用 C# 8,甚至在最近才鼓励我们将其用作库代码的基线目标的 .NET Standard 2.0 库中也是如此。您甚至无法将它与 3.0 之前的 .NET Core 版本一起使用,因为它们也仅支持 .NET Standard 2.0。
调查开始了!-
Jon Skeet 有一个使用 C# 8 的Noda -Time 的 alpha 版本,它只针对 .NET Standard 2.0。他显然期望 C# 8/.NET Standard 2.0 支持 .NET 家族中的所有框架。(另请参阅 Jon 的博文“可空引用类型的第一步”)。
微软员工一直在 GitHub 上讨论 C# 8 可空引用类型的 Visual Studio UI ,并表示他们打算支持旧版csproj(.NET Core SDK 之前的格式csproj)。这是一个非常强烈的迹象,表明 C# 8 将与 .NET Framework 一起使用。[我怀疑他们会在 Visual Studio 2019 语言版本下拉列表已被禁用且 .NET 已与 C# 7.3 绑定后回溯]
csproj
这篇著名的博文发布后不久,一个GitHub 线程讨论了跨平台支持。出现的重要一点是.NET Standard 2.1 将包含一个标记,表示支持接口的默认实现- 该功能需要 CLR 更改,而 .NET Framework 将永远无法使用该更改。这是重要的一点,来自 Microsoft .NET 团队的项目经理 Immo Landwerth:
编译器(例如 C#)应使用此字段的存在来决定是否允许默认接口实现。如果该字段存在,则预计运行时能够加载并执行生成的代码。
IIRC,绝对不会出现在 .NET Framework 上的唯一功能是 DIM(默认接口方法),因为它需要运行时更改。其他功能由类的形状驱动,这些类可能永远不会添加到 .NET Framework,但可以通过您自己的代码或 NuGet(范围、索引、异步迭代器、异步处理)进行填充。
评论说:“设计更复杂的可空用例所需的新可空属性仅在 .NET Core 3.0 和 .NET Standard 2.1 附带的 System.Runtime.dll 中可用...... [并且] 与 .NET Framework 不兼容4.8”
然而,Immo Landwerth在试用可空引用类型一文下评论说:“我们的绝大多数 API 不需要任何自定义属性,因为类型要么是完全通用的,要么不为空”
Ben Hall在 GitHub 上提出了Core 3.0 之外的可为空属性的可用性问题,微软员工的以下评论值得注意:
仅 .net core 3.0 和 .net standard 2.1 将完全支持 C# 8。如果您手动编辑项目文件以将 C# 8 与 .net core 2.1 一起使用,则您处于不受支持的领域。一些 C# 8 特性会运行良好,一些 C# 8 特性运行不太好(例如性能不佳),一些 C# 8 特性会在额外的 hack 下运行,而一些 C# 8 特性根本无法运行。解释起来很复杂。我们不会主动阻止它,因此可以浏览它的专家用户可以这样做。我不建议广泛使用这种不受支持的混搭。
(简·科塔斯)
像您这样愿意理解并围绕它们工作的人可以免费使用 C# 8。关键是,并非所有语言功能都适用于低级目标。
(伊莫兰德韦斯)
Microsoft 未正式支持 C# 8/.NET Framework 组合。他们说,它仅供专家使用。