小编典典

C# 8 是否支持 .NET 框架?

all

在 Visual Studio 2019 高级构建设置中,C# 8 似乎不适用于 .NET Framework 项目,仅(如下图所示)适用于 .NET
Core 3.0 项目:

在此处输入图像描述

C# 8 是否支持 .NET 框架?


阅读 93

收藏
2022-06-15

共1个答案

小编典典

是的,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 及更高版本中执行此操作。

大多数(但不是全部)功能都适用于目标框架。


有效的功能

以下功能仅是语法更改;无论框架如何,它们都可以工作:

可以使用的功能

这些需要 .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

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   <LangVersion>preview</LangVersion>

<Nullable>enable</Nullable>然后,我通过添加到 main 来启用对可为空的引用类型的支持PropertyGroup

<PropertyGroup>
   <Nullable>enable</Nullable>

我重新加载了项目,它构建了。


视觉工作室 2019

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
明白这一点,一切都很好。

然而,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 绑定后回溯]

  • 这篇著名的博文发布后不久,一个GitHub 线程讨论了跨平台支持。出现的重要一点是.NET Standard 2.1 将包含一个标记,表示支持接口的默认实现- 该功能需要 CLR 更改,而 .NET Framework 将永远无法使用该更改。这是重要的一点,来自 Microsoft .NET 团队的项目经理 Immo Landwerth:

编译器(例如 C#)应使用此字段的存在来决定是否允许默认接口实现。如果该字段存在,则预计运行时能够加载并执行生成的代码。

  • 这一切都表明“C# 8.0 仅在实现 .NET Standard 2.1 的平台上受支持”过于简单化了,C#8 将支持 .NET Framework,但由于存在太多不确定性,我在 GitHub 上询问,HaloFour 回答:

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 组合。他们说,它仅供专家使用。

2022-06-15