zoukankan      html  css  js  c++  java
  • C#10新功能预览

    C#10新功能预览

    C#10新功能预览

     

      2021年4月19日微软发布公告称将于今年夏季发布首款64位的 Visual Studio 2022,2021年5月20日又发布了 Visual Studio 2022 线路图,进一步提升开发生产力。与 Visual Studio 黄金搭档的 C# 语言一直都是秒天秒地秒空气的存在。C#10,今天它来了。

     本周早些时候(2021年5月1日),我关注了Mads Torgersen在DotNet SouthWest的一次演讲,他是微软C#语言的首席设计师。他概述了C#10将包含的新酷功能。下面我们一起快速预览。

    record struct

    他首先谈到的是 record 的当前实现是使用类(reference type)作为基对象的。C#10中即将提供一个 record struct,它的基础类型可以是值类型。不同之处在于,常规 record 将通过引用从一个函数传递到另一个函数,而 record struct 将通过其值进行复制。record struct 也将支持 with 表达式。

    同时,还可以向 record 中添加运算符。这两种 record 类型都可以使用。

    record Person(string Name, string Email)
    {
      public static Person operator +(Person first, Person second)
      {
         // TODO 业务逻辑
      }
    }

    required 特性

      C# 团队关注的目标之一是使对象的初始化更容易。这就是为什么可以根据需要对 class,struct,record 或 record struct 添加 required 特性标记。它强制要求这些属性必须赋值。这可以通过构造函数来完成,或者可以通过对象初始化来完成。下面的两个类定义是等效的。如果用required关键字写的话,不设置Name属性就不能实例化Person 。编译器会抛出错误并且无法编译。

    class Person
    {
      public required string Name { get; set; }
      public DateTime DateOfBirth { get; set; }
    }
    
    class Person
    {
      public Person(string name) => Name = name;
    
      public string Name { get; set; }
      public DateTime DateOfBirth { get; set; }
    }

    field 特性

    为了进一步改善属性(properties),可以完全摆脱 backing field。新的关键字 field 将提供对所述支持字段的访问。它对 setter 和 init only 属性都可以使用。

    class Person
    {
      public string Name { get; init => field = value.Trim(); }
      public DateTime DateOfBirth { get; set => field = value.Date; }
    }

    with 表达式

      在下一个版本中也会有一些漂亮的小改进。其中之一就是 with 操作符也将支持匿名类型。

    var foo = new
    {
      Name = "Foo",
      Email = "foo@mail.com"
    };
    var bar = foo with {Name = "Bar"};

    namespace 命名空间

      现在可以创建一个文件,其中的命名空间导入可以在任何地方使用。例如,如果在几乎每个文件中都使用了一个常用的名称空间,例如
    Microsoft.Extensions.Logging.ILogger,那么就可以将全局命名空间 using Microsoft.Extensions.Logging.ILogger 添加到任何.cs文件中(我建议使用Program.cs或专用Imports.cs),整个项目中都可以使用 logger 接口。但是,该方法不适用于整个解决方案(solution)。因为没有人能预测哪些地方需要导入,所以它们是按项目分组到每个项目(project)中。

    C#10新功能预览

     

    C#10新功能预览

     

      随后,还会对 namespace 进行优化。现在 namespace 需要花括号 {} 来对代码进行分组,这意味着所有代码至少要缩进一次。为了节省 tab(或四个空格)和屏幕空间,在文件中的任何位置添加一个 namespace,将使所有代码都属于该namespace。有相关研究表明绝大多数情况下,一个文件中的几乎所有代码都属于同一个 namespace。使用该方案优化后,文件大小会减小,这对于一个解决方案(即使它包含数千个文件)来说可能并不重要,但在
    GitHub/GitLab/BitBucket/...的规模上,我认为这将为他们节省一些空间。如果有人仍想在一个文件中包含多个命名空间,则仍然可以选择使用大括号。

    // 传统方式 LegacyNamespace.cs
    namespace LegacyNamespace
    {
      class Foo
      {
        // ToDo 业务逻辑
      }
    }
    
    // 简化后的方式 SimplifiedNamespace.cs
    namespace SimplifiedNamespace;
    class Bar
    {
      // ToDo 业务逻辑
    }

    lambda 表达式

    lambda 语句也有一些很酷的更新。编译器将更好地支持推断 lambda 签名,并且还可以添加属性。可以指定显式返回类型以帮助编译器理解 lambda。

    var f = Console.WriteLine;
    var f = x => x; // 推断返回类型
    var f = (string x) => x; // 推断签名
    var f = [NotNull] x => x; // 在属性上添加特性
    var f = [NotNull] (int x) => x;
    var f = [return: NotNull] static x => x; // 为返回类型添加特性
    var f = T () => default; // 显示返回类型
    var f = ref int (ref int x) => ref x; // 在 struct 上使用 ref 关键字
    var f = int (x) => x; // 显式指定隐式输入的返回类型
    var f = static void (_) => Console.Write("Help");

    interface接口

      最后,可以在接口上指定静态方法和属性。我知道这将是一个有争议的话题,就像向接口添加默认实现一样。虽然我不喜欢它,然而这可能非常有趣。想象一下,您可以指定接口的默认值或指定创建方法。

    interface IFoo
    {
      static IFoo Empty { get; }
      static operator +(IFoo first, IFoo second);
    }
    class Foo : IFoo
    {
      public static IFoo Empty => new Foo();
      public static operator +(IFoo first, IFoo second) => /* 在此做逻辑计算 */;
    }

    就个人而言,我喜欢这些变化。尤其是 namespace 和 interface 的变化和改进。不管怎样,C#的未来是光明的。


    系列内容:Visual Studio 2022、.NET Core、.NET5、.NET6、C#、C#10


    漫思
  • 相关阅读:
    题解:[HNOI2004]树的计数
    题解:砝码称重
    题解:子矩阵(NOIP2014普及组T4)
    题解:低价购买
    题解:倍增三连击orz
    题解:UVA10140 Prime Distance
    题解:[JSOI2007]建筑抢修
    模板:三分法
    Databinging数据绑定
    开始
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/14883513.html
Copyright © 2011-2022 走看看