C# 9.0 新特性预览 - 类型推导的 new
C# 9.0 新特性预览 - 类型推导的 new
前言
随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们。
目录
[C# 9.0 新特性预览 - 类型推导的 new]
[C# 9.0 新特性预览 - Lambda 中的弃元]
[C# 9.0 新特性预览 - 更简便的空参数检查]
[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]
- C# 3.0新特性系列:隐含类型var
- C#的新特性:可空类型
- 微软免费图书《Introducing Microsoft LINQ》翻译Chapter3.2-和C#相似的VB9.0的语法特性
- C#学习笔记(三)—–C#高级特性:枚举类型和迭代
- C# 数据类型、默认值、new关键字、格式化数值结果表
- C#学习笔记(三)—–C#高级特性:匿名类型
- C# 给枚举类型增加一个备注特性
- VS2005中使用C#的新特性:可空类型
- c# 9.0 特性提案 简化空参数验证代码
- 4、步步为营VS 2008 + .NET 3.5(4) - C# 3.0新特性之LambdaExpressions(Lambda表达式)、QuerySyntax(查询语法)和AnonymousTypes(匿名类型)
- C# 给枚举类型增加一个描述特性
- C# 3.0新特性初步研究 Part1:使用隐含类型的本地变量_C#教程
- 更好的代码 - .NET 引用类型与new 运算符 (C#)
- c# 4.0新特性一览 / New Characteristic of C# 4.0
- Java 8 新特性之泛型的类型推导
- C#类型反射、晚期绑定、特性编程的使用背景与分析
- C# 3.0新特性初步研究 Part1:使用隐含类型的本地变量_C#教程
- C#教程:关于匿名类型的特性
- c# 3.0新特性 隐式类型
- C# 关于匿名类型的特性