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]

  • 相关阅读:
    HDU 2639 Bone Collector II (01背包,第k解)
    POJ 2184 Cow Exhibition 奶牛展(01背包,变形)
    hihoCoder #1165 : 益智游戏 (挑战赛11 B题)
    UVA 562 Dividing coins 分硬币(01背包,简单变形)
    POJ Charm Bracelet 挑饰品 (常规01背包)
    hiho一下 第四十四周 博弈游戏·Nim游戏(直接公式解)
    UVA 624 CD(01背包,要记录路径)
    118 Pascal's Triangle 帕斯卡三角形 杨辉三角形
    117 Populating Next Right Pointers in Each Node II 每个节点的右向指针 II
    116 Populating Next Right Pointers in Each Node 每个节点的右向指针
  • 原文地址:https://www.cnblogs.com/Rwing/p/csharp-9-0-preview-target-typed-new.html
Copyright © 2011-2022 走看看