C# 8支持.NET框架吗?

2ekbmq32  于 2023-03-04  发布在  .NET
关注(0)|答案(2)|浏览(293)

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

C#8支持. NET框架吗?

5jvtdoz2

5jvtdoz21#

    • 是的,C#8可以与. NET Framework**以及Visual Studio 2019中早于. NET Core 3.0/. NET Standard 2.1的其他目标(或更早版本的Visual Studio,如果您install a NuGet package)一起使用。

唯一需要做的事情是在csproj文件中将语言版本设置为8.0。您也可以在Directory.Build.props中执行此操作,以将其应用于解决方案中的所有项目。请阅读下文,了解如何在Visual Studio 2019 16.3版及更高版本中执行此操作。
无论目标框架是什么,大多数(但不是全部)特性都可用。

有效的功能

下列功能仅为语法更改;它们不受框架限制:

  • 静态局部函数
  • 使用声明
  • 空合并赋值
  • 只读成员
  • 一次性参考结构
  • 位置模式
  • 元组模式
  • 开关表达式
  • 它也支持可空引用类型,但是不支持设计更复杂的可空用例所需的新nullable attributes,我将在后面的"血淋淋的细节"一节中更详细地介绍这一点。

可以使用的功能

这些需要. NET Framework中没有的新类型。它们只能与"polyfill" NuGet包或代码文件一起使用:

默认接口成员-不起作用、不能起作用和永远不会起作用

默认接口成员不会在. NET Framework下编译,并且永远不会工作,因为它们需要在CLR中进行运行时更改。. NET CLR现在已冻结,因为. NET Core现在是前进的方向。

编号
下面的C#项目以. NET Framework 4.8为目标并使用C#8可空引用类型,它在Visual Studio 16.2.0中编译。我创建它的方法是选择. NET标准类库模板,然后将其编辑为以. NET Framework为目标:
.国家方案项目j:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net48</TargetFrameworks>
    <LangVersion>8.0</LangVersion>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

.政务司:

namespace ClassLibrary1
{
    public class Class1
    {
        public string? NullableString { get; set; }
    }
}

然后我尝试了一个. NET Framework 4.5.2 WinForms项目,使用了一种遗留的.csproj,并添加了相同的可为null的引用类型属性。我在Visual Studio高级生成设置对话框中更改了语言类型(在16.3中禁用)到latest并保存项目。当然,此时它不会构建。我在文本编辑器中打开了项目文件,并在构建配置PropertyGroup中将latest更改为preview

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

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

<PropertyGroup>
   <Nullable>enable</Nullable>

我重新加载了这个项目,然后它就生成了。
虚拟工作室2019
Visual Studio 2019版本16.3(面向C#8.0的发布版本)的RTM版本中有一项重大更改:语言选择下拉菜单已被禁用:

Microsoft针对此问题的rationale是:
每个框架的每个版本都有一个支持的默认版本,我们不会支持任意版本。为了反映支持的变化,这次提交永久禁用语言版本组合框,并添加一个链接到解释变化的文档。
打开的文档是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中引入的Value Tuples。该功能需要新类型-ValueTuple结构,而在低于4.7的NET Framework版本或早于2.0的. NET Standard中没有这些类型。**但是,**C#7仍然可以在较早版本的. NET中使用。要么没有值元组,要么通过安装System.ValueTuple Nuget package来使用它们。VisualStudio理解这一点,世界上一切都很好。
不过,麦兹也写道:
因此,只有实现. NET Standard 2.1的平台才支持使用C#8.0。

......如果这是真的,就排除了在.NET Framework的 * 任何 * 版本中使用C# 8,甚至是在.NET标准2.0库中使用C#8,直到最近我们才被鼓励将其用作库代码的基准目标。您甚至不能在.NET核心版本3.0之前使用C#8,因为它们也只支持.NET标准2.0。
调查已经开始了!-

  • Jon Skeet有一个Noda-Time的alpha版本,使用的是C#8 ready to go,它只针对.NET标准2.0。他显然希望C#8/.NET标准2.0支持.NET家族中的所有框架。(另请参见Jon的博客文章"First steps with nullable reference types")。
  • Microsoft员工一直在讨论VisualStudioUI for C#8可空引用类型on GitHub,并且声明他们打算支持传统的X1 M9 N1 X(.NET核心SDK之前的格式csproj)。这强烈表明C#8将可用于.NET框架。[我怀疑他们现在会收回这一点,因为Visual Studio 2019语言版本下拉列表已被禁用,.NET已绑定到C# 7.3]
  • 在这篇著名的博客文章发表后不久,一篇关于GitHub thread的文章讨论了跨平台支持的问题。其中一个重要的观点是.NET Standard 2.1 will include a marker that denotes that default implementations of interfaces is supported--该特性需要对CLR进行修改,而这在.NET框架中是永远无法实现的。以下是微软.NET团队项目经理Immo Landwerth的重要观点:

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

  • 这一切都表明“C# 8.0只在实现.NET Standard 2.1的平台上受支持”是一种过于简单化的说法,而且C# 8将支持.NET Framework,但由于存在如此多的不确定性,I asked on GitHub和HaloFour回答说:

IIRC,唯一肯定不会出现在.NET Framework上的特性是DIM(默认接口方法),因为这需要运行时更改。其他特性由类的形状驱动,这些类可能永远不会添加到.NET Framework中,但可以通过您自己的代码或NuGet(范围、索引、异步迭代器、异步处理)进行多边填充。

仅.net core 3.0和.net standard 2.1完全支持C# 8。如果您手动编辑项目文件以将C# 8与.net core 2.1一起使用,则您处于不受支持的状态。有些C# 8功能将碰巧运行良好,有些C# 8功能将运行不太好(例如,性能差),一些C#8特性将在额外的攻击下工作,而且一些C# 8的特性根本就不起作用。2解释起来很复杂。3我们不会主动屏蔽它,这样可以浏览它的Maven用户就可以这样做。我不建议广泛使用这种不受支持的混搭。
(Jan科塔斯)
像您这样愿意理解并解决这些问题的人可以自由地使用C#8。关键是,并非所有的语言特性都适用于底层目标。
(Immo兰德沃思)

买者须知

微软官方并不支持C# 8/.NET框架的组合。他们说,这是仅供Maven使用的。

6l7fqoea

6l7fqoea2#

根据this blog entry,该语言确实与框架绑定:
这意味着使用这些功能所需的类型在.NET Framework 4.8上不可用。同样,默认接口成员实现依赖于新的运行时增强,我们也不会在.NET Runtime 4.8中进行这些增强。
因此,只有实现.NET Standard 2.1的平台才支持使用C# 8.0。保持运行时稳定的需要已经阻止我们在其中实现新的语言特性十多年了。随着现代运行时的并行和开源特性,我们觉得我们可以负责任地再次发展它们。并在做语言设计时牢记这一点。Scott在他的关于.NET核心3. 0和.NET框架4. 8的更新中解释说,.NET框架在未来将看到更少的创新,而是专注于稳定性和可靠性。鉴于此,我们认为它错过一些语言特性总比没有人得到它们好。

相关问题