C# 8.0 新特性

C# 8.0 新特性

作者:Rwing
https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0

原文:https://blogs.msdn.microsoft.com/dotnet/2018/11/12/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 中最重要的新特性的概述。还有一些较小的改进正在进行中,这些改进将在未来几个月逐渐显现出来。

  • Nullable reference types : 可空引用类型
  • Async streams : 异步流
  • Ranges and indices : 范围和索引
  • Default implementations of interface members : 接口成员的默认实现
  • Recursive patterns : 递归的模式匹配
  • Switch expressions Switch : 表达式
  • Target-typed new-expressions : 已知目标类型的新表达式

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#

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Technology authors write for a demanding group of people (for the best of possible reasons). You know that building software solutions using any platform or language is extremely complicated and is specific to your department, company, client base, and subject matter. Perhaps you work in the electronic publishing industry, develop systems for the state or local government, or work at NASA or a branch of the military. Collectively, we have worked in a variety of industries, including developing children’s educational software (Oregon Trail/Amazon Trail), various enterprise systems, and projects within the medical and financial industries. The chances are almost 100 percent that the code you write at your place of employment has little to do with the code we have authored over the years. Therefore, in this book, we have deliberately chosen to avoid creating demonstrations that tie the example code to a specific industry or vein of programming. Given this, we explain C#, OOP, the CLR, and the .NET base class libraries using industry-agnostic examples. Rather than having every blessed example fill a grid with data, calculate payroll, or whatnot, we stick to subject matter we can all relate to: automobiles (with some geometric structures and employee payroll systems thrown in for good measure). And that’s where you come in. Our job is to explain the C# programming language and the core aspects of the .NET platform the best we possibly can. As well, we will do everything we can to equip you with the tools and strategies you need to continue your studies at this book’s conclusion. Your job is to take this information and apply it to your specific programming assignments. We obviously understand that your projects most likely don’t revolve around automobiles with friendly pet names (Zippy the BMW or a Yugo named Clunker, among others), but that’s what applied knowledge is all about! Rest assured, once you understand the topics and concepts presented within this text, you wi

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值