[翻译] C# 8.0 新特性

简介: 原文:[翻译] C# 8.0 新特性原文: Building C# 8.0 [译注:原文主标题如此,但内容大部分为新特性介绍,所以意译标题为 "C# 8.0 新特性"] C# 的下一个主要版本是 8.0。
原文: [翻译] C# 8.0 新特性

原文: Building C# 8.0
[译注:原文主标题如此,但内容大部分为新特性介绍,所以意译标题为 "C# 8.0 新特性"]

C# 的下一个主要版本是 8.0。我们已经为它工作了很长一段时间,即使我们构建并发布了次要版本 C# 7.1, 7.2 和 7.3,我仍然对 8.0 将带来的新特性感到非常兴奋。

目前的计划是 C# 8.0 将与 .NET Core 3.0 同时发布。然而,随着我们正在开发的 Visual Studio 2019 的预览版,这些特性将开始活跃起来。当这些出来的时候,您就可以开始尝试它们,我们将提供有关各个特性的更多细节。这篇文章的目的是向您简述预期的内容,以及如何理解它们。

C# 8.0 新特性

下面是 C# 8.0 中最重要的新特性的概述。还有一些较小的改进正在进行中,这些改进将在未来几个月逐渐显现出来。

Nullable reference types 可空引用类型

此特性的目的是帮助处理无处不在的空引用异常,这种异常已经困扰了半个世纪的面向对象编程。

这个特性阻止您将 null 放入普通引用类型中(如字符串),从而使这些类型不可为 null!不过它是温和的提示警告,而不是错误。所以,它会让现有代码出现新的警告,因此您必须有选择的使用该功能 (您可以在项目、文件甚至行级别执行此操作)。

string s = null; // Warning: Assignment of null to non-nullable reference type

如果您确实想要 null 怎么办?可以使用一个可空引用类型,例如 string? 这样:

string? s = null; // Ok

当您尝试使用可空引用类型时,你首先需要检查是否为空。编译器会分析代码流,以查看 null 值是否可以将其用于当前位置:

void M(string? s)
{
    Console.WriteLine(s.Length); // Warning: Possible null reference exception
    if (s != null)
    {
        Console.WriteLine(s.Length); // Ok: You won't get here if s is null
    }
}

这个特性的要点是,C# 允许您表达“可空的意图”,并且在您不遵守它时候发出警告。

Async streams 异步流

C# 5.0 的 async/await 特性使您可以用非常简单的代码消费(或生产)异步结果, 而无需回调:

async Task<int> GetBigResultAsync()
{
    var result = await GetResultAsync();
    if (result > 20) return result; 
    else return -1;
}

如果您想要消费(或生产)连续的结果流(例如您可能从物联网设备或云服务获得),则没有那么有用。 异步流就是为此而存在的。

如果您想要消费(或生产)连续的结果流(例如您可能从物联网设备或云服务获得),则没有那么有用。 异步流就是为此而存在的。

我们现在介绍一下您所期望的 IAsyncEnumerable<T>,即 IEnumerable<T> 的异步版本。允许您 await foreach 以消费它们的元素,并 yield return 以生产元素。

async IAsyncEnumerable<int> GetBigResultsAsync()
{
    await foreach (var result in GetResultsAsync())
    {
        if (result > 20) yield return result; 
    }
}

Ranges and indices 范围和索引

我们正在添加一个类型 Index,可用于索引。您可以创建一个整型来表示从头开始的索引,或者一个 ^ 前缀的从结尾表示的索引:

Index i1 = 3;  // number 3 from beginning
Index i2 = ^4; // number 4 from end
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"

我们还引入了一个 Range 类型,它由两个 Index 组成,一个用于开始,一个用于结束,并且可以用 x..y 这样的范围表达式来编写。然后,您可以使用 Range 进行索引来生成切片:

var slice = a[i1..i2]; // { 3, 4, 5 }

Default implementations of interface members 接口成员的默认实现

现在,一旦你发布了一个接口,游戏就结束了:你不能在不破坏它的所有现有实现的情况下向它添加成员。

在 C# 8.0 中,我们允许您为接口成员提供一个默认实现。因此,如果某人没有实现该成员(可能因为他们编写代码时还没有该成员),他们将只得到默认的实现。

interface ILogger
{
    void Log(LogLevel level, string message);
    void Log(Exception ex) => Log(LogLevel.Error, ex.ToString()); // New overload
}

class ConsoleLogger : ILogger
{
    public void Log(LogLevel level, string message) { ... }
    // Log(Exception) gets default implementation
}

ConsoleLogger 类不必实现 ILogger 中 Log(Exception) 重载函数,因为它已经定义了默认实现。现在只要提供了一个默认实现,您就可以添加新的成员到已经存在的公开接口中了。

Recursive patterns 递归的模式匹配

在模式匹配中,现在允许模式中包含其他模式。

IEnumerable<string> GetEnrollees()
{
    foreach (var p in People)
    {
        if (p is Student { Graduated: false, Name: string name }) yield return name;
    }
}

这个模式 Student { Graduated: false, Name: string name } 会检查 Person 是否是 Student,然后将常量模式 false 应用于 Graduated 属性以查看它们是否已毕业,并将模式字符串 name 添加到其 Name 属性中,得到他们的名字(如果非空)。因此,如果 p 是 Student,没有毕业并且具有非空的名字,则返回该名字。

Switch expressions Switch 表达式

带有模式的 switch 语句在 C# 7.0 中非常强大,但编写起来很麻烦。switch 表达式是一个“轻量级”版本,其中所有情况都是表达式:

var area = figure switch 
{
    Line _      => 0,
    Rectangle r => r.Width * r.Height,
    Circle c    => c.Radius * 2.0 * Math.PI,
    _           => throw new UnknownFigureException(figure)
};

Target-typed new-expressions 已知目标类型的新表达式

在许多情况下,当您创建新对象时,类型已经可以从上下文中知道。在这些情况下,可以省略类型:

Point[] ps = { new (1, 4), new (3,-2), new (9, 5) }; // all Points

该功能的实现由社区成员提供,谢谢!

平台依赖性

大多数 C# 8.0 语言特性都可以在任何版本的 .NET 上运行。但是,其中一些具有平台依赖性。

Async streams, Index 和 Range 都依赖于 .NET Standard 2.1 的新类型。正如 Immo 在他的文章《公布.NET Standard 2.1》所说的那样,.NET Core 3.0 、Xamarin 、Unity 和 Mono 都将实现 .NET Standard 2.1,但 .NET Framework 4.8 不会。这意味着当您将 C# 8.0 指向到 .NET Framework 4.8 时,使用这些功能所需的类型将不可用。

与往常一样,C# 编译器对它所依赖的类型非常宽容。如果它能找到具有正确的名字和形态的类型,则很乐意将它们作为目标。

默认接口实现依赖于新的增强运行时,我们也不会在 .NET Runtime 4.8 中实现这些。因此,此特性不适用于 .NET Framework 4.8 和旧版本的 .NET。

十余年间,为了保持运行时的稳定,我们无法在其中实现新的语言特性。随着现代化运行时的并行性和开源性,我们觉得可以负责任地去重新开发它们,并在考虑到这一点时进行语言设计。 Scott 在其 .NET Core 3.0 和 .NET Framework 4.8 更新中解释说,.NET Framework 将来会看到较少的创新,而是关注稳定性和可靠性。考虑到这一点,我们认为,直接忽略某些语言特性会好一些。

想要了解更多?

C# 语言的设计过程是开源的,在这个repo中。如果您不经常跟进,可能会有点混乱和力不从心。语言设计的核心是语言设计会议,记录在 C# 语言设计日记

大约一年前,我写了一篇介绍C#中的可空引用类型的文章。您仍然可以阅读它并得到一些信息。。

您还可以观看视频,例如 Microsoft Build 2018 大会上的 C# 未来,或者 .NET Conf 2018 大会上的即将到来的 C#,它展示了其中一些特性。

Kathleen 有一篇很好的帖子来阐述了 .Net Core 3.0 中的 Visual Basic 的计划。

当我们开始将这些功能作为 Visual Studio 2019 预览版的一部分发布时,我们还将发布有关各个功能的更多详细信息。

就个人而言,我迫不及待地要把它们交到你们所有人手中!

Happy hacking,

Mads Torgersen, Design Lead for C#

目录
相关文章
|
6月前
|
C#
C#学习相关系列之数据类型类的三大特性(二)
C#学习相关系列之数据类型类的三大特性(二)
|
6月前
|
编译器 C# 开发者
C# 11.0中的新特性:覆盖默认接口方法
C# 11.0进一步增强了接口的灵活性,引入了覆盖默认接口方法的能力。这一新特性允许类在实现接口时,不仅可以提供接口中未实现的方法的具体实现,还可以覆盖接口中定义的默认方法实现。本文将详细介绍C# 11.0中接口默认方法覆盖的工作原理、使用场景及其对现有代码的影响,帮助开发者更好地理解和应用这一新功能。
|
6月前
|
编译器 C# 开发者
C# 9.0中的顶级语句:简化程序入口的新特性
【1月更文挑战第13天】本文介绍了C# 9.0中引入的顶级语句(Top-level statements)特性,该特性允许开发者在不使用传统的类和方法结构的情况下编写简洁的程序入口代码。文章详细阐述了顶级语句的语法、使用场景以及与传统程序结构的区别,并通过示例代码展示了其在实际应用中的便捷性。
|
16天前
|
编译器 C# 开发者
C# 9.0 新特性解析
C# 9.0 是微软在2020年11月随.NET 5.0发布的重大更新,带来了一系列新特性和改进,如记录类型、初始化器增强、顶级语句、模式匹配增强、目标类型的新表达式、属性模式和空值处理操作符等,旨在提升开发效率和代码可读性。本文将详细介绍这些新特性,并提供代码示例和常见问题解答。
33 7
C# 9.0 新特性解析
|
14天前
|
C# 开发者
C# 10.0 新特性解析
C# 10.0 在性能、可读性和开发效率方面进行了多项增强。本文介绍了文件范围的命名空间、记录结构体、只读结构体、局部函数的递归优化、改进的模式匹配和 lambda 表达式等新特性,并通过代码示例帮助理解这些特性。
28 2
|
2月前
|
编译器 C# Android开发
震惊!Uno Platform 与 C# 最新特性的完美融合,你不可不知的跨平台开发秘籍!
Uno Platform 是一个强大的跨平台应用开发框架,支持 Windows、macOS、iOS、Android 和 WebAssembly,采用 C# 和 XAML 进行编程。C# 作为其核心语言,持续推出新特性,如可空引用类型、异步流、记录类型和顶级语句等,极大地提升了开发效率。要在 Uno Platform 中使用最新 C# 特性,需确保开发环境支持相应版本,并正确配置编译器选项。通过示例展示了如何在 Uno Platform 中应用可空引用类型、异步流、记录类型及顶级语句等功能,帮助开发者更好地构建高效、优质的跨平台应用。
208 59
|
1月前
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
36 1
|
3月前
|
开发框架 .NET 编译器
总结一下 C# 如何自定义特性 Attribute 并进行应用
总结一下 C# 如何自定义特性 Attribute 并进行应用
|
3月前
|
C# 索引
C#各大版本特性
C#各大版本特性
76 0
|
6月前
|
开发框架 .NET Java
ASP.NET Core高级编程--C#基本特性(一)
本文章简略介绍C#的部分特性