一探即将到来的 C# 10

前言

本来因为懒不想写这篇文章,但是不少人表示有兴趣,于是最后决定还是写一下。

.NET 6 最近几个预览版一直都在开发体验(如 hot reload、linker 等)、平台支持(如 Android、iOS 等)、工具链(如 crossgen2、PGO 工具和 wasm 的 AOT 等)、JIT(如 LSRA、Jump threading、PGO 和 guarded devirtualization 以及使 struct 保持在寄存器上等)、GC(如 Regions 等)以及 BCL(如 TimeOnly、DateOnly 以及 Json DOM 等)方面做改进,然而却一直没有公布 C# 10 的任何内容,即使在 Build 2021 大会上也没有提及这方面内容。然而实际上不少特性的实现已经接近尾声了,那么让我们提前来看看 C# 10 可以为我们带来什么东西。

当然,不是所有下面列出的特性都会一定进入 C# 10,也可能会和本文有所出入,我在每一个特性后面加了一个百分比表示最终实装的可能性,仅供参考。

Backing Fields(60%)

相信不少人在编写属性的时候,总是想“如果能不用手动写字段的定义就好了”,现在这个梦想成真了:

private int myInt;
public int MyInt { get => myInt; set => myInt = value; }

C# 10 中新增了一个 field,当使用它时会自动为属性创建字段定义,不需要再手动定义字段了。

public int MyInt { get => field; set => field = value; }

Record Structs(100%)

Records 此前只支持 class,但是现在同样支持 struct 啦,于是你可以定义值类型的 record,避免不必要的堆内存分配:

record struct Point(int X, int Y);

with on Anonymous Objects(80%)

此前 with 只能配合 records 使用,但是现在它被扩展到了匿名对象上,你可以通过 with 来创建匿名对象的副本并且修改它的值啦:

var foo = new { A = 1, B = "test", C = 4.4 };
var bar = foo with { A = 3 };
Console.WriteLine((bar.A, bar.B, bar.C)); // (3, test, 4.4)

Global Usings(80%)

此前 using 语句的生效范围是单个文件的,如果你想使用一些 namespace,或者定义一系列的类型别名在整个项目内使用,那么你就需要这样:

using System.Linq;
using static System.Math;
using i32 = System.Int32;
using i64 = System.Int64;

然后在每个文件中重复一遍。但是现在不需要了,你可以定义全局的 using 了:

global using System.Linq;
global using static System.Math;
global using i32 = System.Int32;
global using i64 = System.Int64;

然后在整个项目中就都可以用了。

File Scoped Namespace(90%)

C# 10 开始你将能够在文件顶部指定该文件的 namespace,而不需要写一个 namespace 然后把其他代码都嵌套在大括号里面,毕竟绝大多数情况下,我们在写代码时一个文件里确实只会写一个 namespace,这样可以减少一层嵌套也是很不错的:

namespace MyProject;class MyClass
{// ...
}

如果采用这样的写法,每一个文件将只能声明一个 namespace。

Constant Interpolated String(100%)

顾名思义,常量字符串插值:

const string a = "foo";
const string b = $"{a}_bar"; // foo_bar

常量字符串插值将在编译时完成。

Lambda Improvements(100%)

C# 10 大幅度改进了 lambda,扩展了使用场景,并改进了一系列的推导,提出自然委托类型,还函数上升至 first-class。

支持 Attributes

f = [Foo] (x) => x; // 给 lambda 设置
f = [return: Foo] (x) => x; // 给 lambda 返回值设置
f = ([Foo] x) => x; // 给 lambda 参数设置

支持显示指定返回值类型

此前 C# 的 lambda 返回值类型靠推导,C# 10 开始允许在参数列表最前面显示指定 lambda 类型了:

f = int () => 4;

支持 ref 等修饰

f = ref int (ref int x) => ref x; // 返回一个参数的引用

First-class Functions

方法可以被隐式转换到 Delegate,使得函数上升至 first-class。

Delegate f = 1.GetHashCode; // Func<int>
object g = 2.ToString; // object(Func<string>)
var s = (int x) => x; // Func<int, int>

将函数作为变量,然后传给另一个函数的参数:

void Foo(Func<int> f)
{Console.WriteLine(f());
}int Bar()
{return 5;
}var baz = Bar;
Foo(baz);

Natural Delegate Types

lambda 现在会自动创建自然委托类型。

可以用 var 来创建委托了:

var f = () => 1; // Func<int>
var g = string (int x, string y) => $"{y}{x}"; // Func<int, string, string>
var g = "test".GetHashCode; // Func<int>

调用 lambdas

得益于上述改进,创建的类型明确的 lambda 可以直接调用了。

var zero = ((int x) => x)(0); // 0

Caller Expression Attribute(80%)

现在,CallerArgumentExpression 这个 attribute 终于有用了。借助这个 attribute,编译器会自动填充调用参数的表达式字符串,例如:

void Foo(int value, [CallerArgumentExpression("value")] string? expression = null)
{Console.WriteLine(expression + " " + value);
}

当你这样调用时:

Foo(4 + 5);

会输出 4 + 5 = 9。这对测试极其有用,因为你可以输出 assert 的原表达式了:

static void Assert(bool value, [CallerArgumentExpression("value")] string? expr = null)
{if (!value) throw new AssertFailureException(expr);
}

default 支持解构(100%)

default 现在支持解构了,因此可以给 tuples 直接赋值。

(int a, int b, int c) = default; // (0, 0, 0)

List Patterns(100%)

Pattern Matching 的最后一块版图:list patterns,终于补齐了。

void Foo(List<int> list)
{switch (list){case [4]:Console.WriteLine("长度为 4");break;case { 1, 2, 3 }:Console.WriteLine("元素是 1, 2, 3");break;case { 1, 2, .., var x, 5 }:Console.WriteLine($"前两个元素是 1, 2,最后一个元素是 5,倒数第二个元素是 {x}");break;default:Console.WriteLine("其他");}
}

同样的,该 pattern 也是 recursive 的,因此你可以嵌套其他 patterns。

除了上述 switch statements 的用法,在 if 以及 switch expressions 等地方也同样可用,例如:

void Foo(List<int> list)
{var result = list switch{[4] => ...,{ 1, 2, 3 } => ...,{ 1, 2, .., var x, 5 } => ...,_ => ...};
}

Abstract Static Member in Interfaces(100%)

C# 10 中,接口可以声明抽象静态成员了,.NET 的类型系统正式具备 virtual static dispatch 能力。

例如,你想定义一个可加而且有零的接口 IMonoid

interface IMonoid<T> where T : IMonoid<T>
{abstract static T Zero { get; }abstract static T operator+(T l, T r);
}

然后可以对其进行实现,例如这里的 MyInt

public class MyInt : IMonoid<MyInt>
{public MyInt(int val) { Value = val; }public static MyInt Zero { get; } = new MyInt(0);public static MyInt operator+(MyInt l, MyInt r) => new MyInt(l.Value + r.Value);public int Value { get; }
}

然后就能写出一个方法对 IMoniod<T> 进行求和了,这里为了方便写成扩展方法:

public static class IMonoidExtensions
{public static T Sum<T>(this IEnumerable<T> t) where T : IMonoid<T>{var result = T.Zero;foreach (var i in t) result += i;return result;}
}

最后调用:

List<MyInt> list = new() { new(1), new(2), new(3) };
Console.WriteLine(list.Sum().Value); // 6

这个特性同样也会对 .NET BCL 做出改进,会新增诸如 IAddable<T>INumeric<T> 的接口,并为适用的已有类型实现。

总结

以上就是在 C# 10 的大部分新特性介绍了,虽然不保证最终效果和本文效果一致,但是也能看到一个大概的方向。

从 interface 的改进上我们可以看到一个好的预兆:.NET 终于开始动类型系统了。2008 年至今几乎没有变过的 CTS 显然逐渐不能适应语言发展的需要,而 .NET 团队也明确给出了信息表明要在 C# 11 前后对类型系统集中进行改进,现在只是一个开始,相信不久之后也将能看到 traits、union types、bottom types 和 HKT 等的实装。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/301921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

预售┃没有标题,配得上这款“俄罗斯方块”

▲数据汪特别推荐点击上图进入玩酷屋在之前的文章时&#xff0c;马斯提到数学存在一种现象叫“梯次掉队”&#xff0c;原因在于孩子的数学思维地基没有打牢。&#xff08;传送门&#xff09;提到初中孩子需要空间想象能力时&#xff0c;很多父母疑惑为何需要&#xff1f;关于这…

c mysql binlog_Mysql Binlog

一&#xff0e;Mysql Binlog格式介绍Mysql binlog日志有三种格式&#xff0c;分别为Statement,MiXED,以及ROW&#xff01;1.Statement&#xff1a;每一条会修改数据的sql都会记录在binlog中。优点&#xff1a;不需要记录每一行的变化&#xff0c;减少了binlog日志量&#xff0c…

读Getting Started With Windows PowerShell笔记

使用中Powershell的操作跟Linux中的终端操作很多地方是一致的&#xff0c;当然&#xff0c;还是有着Windows自己的特色&#xff0c;比如&#xff0c;不分大小写。之前命令行中的命令大部分在这里也可以用&#xff0c;而且用法一样。选中后点右键&#xff0c;即复制到剪切板。不…

NET问答: String 和 string 到底有什么区别?

咨询区 Peter O.&#xff1a;开门见山&#xff0c;参考如下例子&#xff1a;string s "Hello world!"; String s "Hello world!";请问这两者有什么区别&#xff0c;在实际使用上要注意一些什么&#xff1f;回答区 Derek Park&#xff1a;string 是 C# 中…

mysql 5.7.6 5.7.19_MySQL数据库之Mysql 5.7.19 免安装版遇到的坑(收藏)

本文主要向大家介绍MySQL数据库之Mysql 5.7.19 免安装版遇到的坑(收藏)了 &#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习MySQL数据库有所帮助。1、从官网下载64位zip文件。2、把zip解压到一个位置&#xff0c;此位置为安装为安装位置3、如果有以前的mysql 如…

LVS负载均衡-NET、DR模式配置

模型一&#xff1a;NAT模型的配置 实验环境&#xff1a; 采用VMware虚拟机&#xff0c;版本6.0.5 操作系统&#xff1a;Red Hat Enterprise Linux 5 (2.6.18) 虚拟机1&#xff1a;充当Director&#xff1a;网卡1(桥接):192.168.0.33&#xff08;对外&#xff09;&#xff0c;网…

编程语言的“别样”编年史

全世界只有3.14 % 的人关注了数据与算法之美代码是一门语言&#xff0c;这门语言搭建了人与计算机沟通的桥梁。通过编写代码&#xff0c;人类可以“命令”计算机开发网页、开发软件、搭建游戏... ... 这门语言并不是上帝的发明&#xff0c;它是前辈们发挥聪明才智创造出来的&am…

mysql目录树_无限级目录树+记忆节点状态(PHP+mysql)

借鉴 网友 iuhxq 的设计制作而成的目录树&#xff0c;在此感谢 iuhxq 的代码对我大帮助。特点&#xff1a;1、无限级节点。2、直接产生html代码&#xff0c;容易修改。3、目录清楚&#xff0c;类似于资源管理器&#xff0c;(csdn论坛的&#xff0c;层数多了就不容易分清楚层次了…

NET问答: 如何使用 C# 比较两个 byte[] 的相等性 ?

咨询区 Hafthor&#xff1a;我现在业务中遇到了一个场景&#xff1a;如何简洁高效的判断两个 byte[] 的相等性&#xff1f;我现在是这么实现的&#xff0c;有一点繁琐&#xff1a;static bool ByteArrayCompare(byte[] a1, byte[] a2) {if (a1.Length ! a2.Length)return false…

也可以改为while(input[0])或while(cininput[0])

2019独角兽企业重金招聘Python工程师标准>>> <<c primer plus>> // static.cpp -- using a static local variable #include <iostream> // constants const int ArSize 10; // function prototype void strcount(const char * str); int main()…

.NET Core HttpClient请求异常分析

【导读】最近项目上每天间断性捕获到HttpClient请求异常&#xff0c;感觉有点奇怪&#xff0c;于是乎观察了两三天&#xff0c;通过日志以及对接方沟通确认等等&#xff0c;查看对应版本源码&#xff0c;尝试添加部分配置发布后&#xff0c;观察十几小时暂无异常情况出现&#…

python 小甲鱼 代码_Python小代码

先自我介绍一下&#xff0c;本人是正在自学Python的小白&#xff0c;没事分享一下自己写的小代码&#xff0c;欢迎在评论区补充。游戏管理系统&#xff1a;代码如下&#xff1a;def healthe(m):if m"Y"or y:print("欢迎&#xff0c;请进入游戏&#xff01;"…

原来这些行业的“潜规则”是这样的...

全世界只有3.14 % 的人关注了数据与算法之美在日常生活中&#xff0c;我们往往受限于专业和工作&#xff0c;对自己所处行业之外的事物了解不多。今天&#xff0c;数据汪带大家扒一扒各个行业中不为人知的“潜规则”&#xff0c;看看你们知道几个&#xff1f;看完上面20个“潜规…

“工业互联网平台“将成为工业制造企业的标配

目 录1. 概述2. 背景3. 评述1. 概述“‘工业互联网平台’将成为工业制造企业的标配”的命题既是基于工业生产企业现实情况的判断&#xff0c;又是对工业企业未来发展的需求判断。前途是光明的&#xff0c;但是道路是曲折的。前途的光明是基于工业企业现实…

5.[BX]和Loop指令

1.Debug和MASN中读取内存单元的区别&#xff1a;Debug中:mov ax,0ffffhmov ds,axmov al,[1]MASN中:mov ax,0ffffhmov ds,axmov bx,1mov al,[bx]或者mov ax,0ffffhmov ds,axmov al,ds:[1]2.Loop指令assume cs:codecode sementmov ax,2mov cx,3s: add ax,axloop scode ednsend 其…

linux mysql安装教程 方大帝_discuz论坛出现Can not connect to MySQL server错误的解决方法...

网站出现了问题&#xff0c;大家一定很着急吧&#xff0c;特别是做网站的&#xff0c;这几天有一台MySQL数据库服务器频繁出现掉线&#xff0c;经排查&#xff0c;并没有哪个网站受攻击&#xff0c;网上搜索了一下&#xff0c;很多人都碰到这问题&#xff0c;全是Windows系统上…

预售┃每个人都应该学习编程,因为它会教你如何思考

▲数据汪特别推荐点击上图进入玩酷屋扎克伯格11岁开始学习编程&#xff0c;创办Facebook&#xff1b;比尔盖茨13岁学习编程&#xff0c;创办微软……乔布斯说&#xff1a;“每一个人都应该学习电脑编程&#xff0c;因为它会教你如何思考。"现在在北京上海&#xff0c;顶级…

数据库(杂)

like查询是区分大小写的转载于:https://blog.51cto.com/cyxinda/1226040

python3抓取图片_通过Python3 爬虫抓取漫画图片

引言&#xff1a;最近闲来无事所以想着学习下python3&#xff0c;看了好长时间的文档&#xff0c;于是用python3写了一个漫画抓取的程序&#xff0c;好了 废话不多说上码&#xff01;第一步&#xff1a;准备环境 和类库&#xff0c;我用的是python3.5 禁用 python2.x &…

被同事嘲笑说技术方案没深度?

大家好&#xff0c;我是Z哥。程序员群体中有个很好玩的现象。工作年限短的程序员热衷于设计“高大上”的技术方案&#xff0c;而工作年限长的则对技术方案好像不太感冒&#xff0c;上手就撸代码。然后呢&#xff0c;年限短的程序员们想的技术方案又不好意思拿出来讲&#xff0c…