zoukankan      html  css  js  c++  java
  • C# 9.0 新特性预览

    C# 9.0 新特性预览 - 类型推导的 new

    前言

    随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们。

    目录

    [C# 9.0 新特性预览 - 类型推导的 new]
    [C# 9.0 新特性预览 - 空参数校验]
    [C# 9.0 新特性预览 - Lambda 中的弃元]
    [C# 9.0 新特性预览 - Record 类型]
    [C# 9.0 新特性预览 - 模式匹配的改善]
    [C# 9.0 新特性预览 - 其他小的变化]

    具有类型推导的 new 表达式 (Target-typed new expressions)

    这是一个本应随着 C# 8.0 发布的语言特性,但因种种原因在发布 C# 8.0 的最后关头,它被移出了最终的发布版本,下面我们来认识认识它。
    大家都知道,C# 在3.0中新增 var 关键字来做隐式类型声明,把繁重的声明语法简化了。

    Dictionary<string, List<int>> field = new Dictionary<string, List<int>>()
    // 可以简化为
    var field = new Dictionary<string, List<int>>()
    

    var 关键字的基本原理不再复述,简单说就是编译器可以根据等号后面的类型推导出 var 的类型,那么是不是也可以反过来,我们先声明类型,接下来的 new 关键字后面就不用写类型了呢?于是本文介绍的特性来了:

    Dictionary<string, List<int>> field = new Dictionary<string, List<int>>()
    // C# 9.0 中可以写成
    Dictionary<string, List<int>> field = new()
    

    从以上代码可以看出语法很简单,即省略了繁琐的可以推导出的类型。
    其语法 Spec 如下:

    'new' '(' argument_list? ')' object_or_collection_initializer?
    

    搭配初始化器,我们可以进一步简化带有初始值的初始化。

    Dictionary<string, List<int>> field = new() {
        { "item1", new() { 1, 2, 3 } }
    };
    

    进一步展示该语法在各种情况下的使用

    在所有可以推导出类型的上下文中,都可以使用,例如:

    XmlReader.Create(reader, new() { IgnoreWhitespace = true });
    

    带有参数的构造方法:

    class C {
        C(params int[] p) {}
    }
    
    C c = new(1, 2, 3);
    

    调用方法时:

    class A {}
    static void M(A a) {};
    
    M(a: new());
    

    配合对象初始化器:

    X x = new() { field = 42 };
    

    泛型的类型推导,需要注意,要有一个显示类型声明才能正确推导:

    void M<T>(T t1, T t2) {}
    
    M(new X(), new());
    

    类似的,数组的声明

    var arr = new[] {new X(), new()};
    

    不适用此特性的场景

    值类型的初始化,可以使用 default 替代

    int x = new(); // ERROR
    Struct y = new(); // ERROR
    

    使用 as 操作时无法正确推导

    Console.Write(new() as X); // ERROR
    

    自然,使用 var 时也无法推导

    var x = new(); // ERROR
    

    有歧义的重载

    void M(object a, X b) => Console.Write($"{a} {b}");
    void M(X a, object b) => Console.Write($"{a} {b}");
    
    M(new(), new()); // ERROR
    

    需要注意的地方

    这个新语法 new(),比较容易与匿名类型语法混淆 new{},它们两个是完全不同的东西,需要注意一下。

    参考

    [Proposal: Target-typed new expressions]
    [Unit test: TargetTypedNewTests.cs]

  • 相关阅读:
    BZOJ 3514 Codechef MARCH14 GERALD07加强版
    WT
    Codeforces 348
    POI 2010
    Codeforces 336
    MVC实例及用三层架构实现对学生信息的增删改查
    欠拟合和过拟合
    线性回归案例
    梯度下降法介绍
    线性回归的损失函数和梯度下降
  • 原文地址:https://www.cnblogs.com/Rwing/p/csharp-9-0-preview-target-typed-new.html
Copyright © 2011-2022 走看看