一:背景

1. 讲故事

好消息,.NET 5.0 终于在2020年6月10日发布了第五个预览版,眼尖的同学一定看到了在这个版本中终于支持了 C# 9.0,此处有掌声,太好了!!!

.Net5官方链接

可以看到目前的C#9还是预览版,实现了一部分新语法供开发者提前尝鲜,从github的roslyn仓库上可以看到目前准备实现 17个新特性,现阶段已经实现了8个,其中的 In Progress 表示正在开发中。

新特性预览

2. 安装必备

找好你自己的vs版本类型哦。。。

二:新特性研究

1. Target-typed new

这个取名一定要留给学易经的大师傅,没见过世面的我不敢造次,取得不佳影响时运,所谓 运去金成铁, 时来铁似金 ,不过大概意思就是说直接new你定义的局部变量的类型,用issues中总结的话就是:


Summary: Allow Point p = new (x, y);
Shipped in preview in 16.7p1.

接下来就是全部代码,看看使用前使用后 的具体差别。


class Program
{
static void Main(string[] args)
{
//老语法
var person = new Person("mary", "123456"); //新语法
Person person2 = new("mary", "123456"); Console.WriteLine($"person={person}person2={person2}");
}
} public class Person
{
private string username;
private string password; public Person(string username, string password)
{
this.username = username;
this.password = password;
} public override string ToString()
{
return $"username={username},password={password} \n";
}
}

然后用ilspy去看看下面的il代码,是不是省略了Person,让自己心里踏实一点。

总的来说这语法还行吧,能起到延长键盘使用寿命的功效。

2. Lambda discard parameters

从字面上看大概就是说可以在lambda上使用取消参数,听起来怪怪的,那本意是什么呢?有时候lambda上的匿名方法签名的参数是不需要的,但在以前必须实打实的定义,这样就会污染方法体,也就是可以在body中被访问,如下图:

但有时候因为客观原因必须使用Func<int,int,int>这样的委托,而且还不想让方法签名的参数污染方法体,我猜测在函数式编程中有这样的场景吧,可能有点类似MVC中的EmptyResult效果。

好了,我想你大概知道啥意思了,接下来实操一把。。。


Func<int, int, int> func = (_, _) =>
{
return 0;
}; var result = func(10, 20);

从图中可以看到,我在方法体中是找不到所谓的 _ 变量的,这就神奇了,怎么做到的呢? 带着这个好奇心看看它的IL代码是个什么样子。


.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2048
// Code size 45 (0x2d)
.maxstack 3
.entrypoint
.locals init (
[0] class [System.Runtime]System.Func`3<int32, int32, int32> func,
[1] int32 result
) IL_0000: nop
IL_0001: ldsfld class [System.Runtime]System.Func`3<int32, int32, int32> ConsoleApp1.Program/'<>c'::'<>9__0_0'
IL_0006: dup
IL_0007: brtrue.s IL_0020 IL_0009: pop
IL_000a: ldsfld class ConsoleApp1.Program/'<>c' ConsoleApp1.Program/'<>c'::'<>9'
IL_000f: ldftn instance int32 ConsoleApp1.Program/'<>c'::'<Main>b__0_0'(int32, int32)
IL_0015: newobj instance void class [System.Runtime]System.Func`3<int32, int32, int32>::.ctor(object, native int)
IL_001a: dup
IL_001b: stsfld class [System.Runtime]System.Func`3<int32, int32, int32> ConsoleApp1.Program/'<>c'::'<>9__0_0' IL_0020: stloc.0
IL_0021: ldloc.0
IL_0022: ldc.i4.s 10
IL_0024: ldc.i4.s 20
IL_0026: callvirt instance !2 class [System.Runtime]System.Func`3<int32, int32, int32>::Invoke(!0, !1)
IL_002b: stloc.1
IL_002c: ret
} // end of method Program::Main

从上面的IL代码来看 匿名方法 变成了<>c类的<Main>b__0_0方法,完整签名: ConsoleApp1.Program/'<>c'::'<Main>b__0_0'(int32, int32),然后再找一下 <Main>b__0_0 方法的定义。


.class nested private auto ansi sealed serializable beforefieldinit '<>c'
extends [System.Runtime]System.Object
.method assembly hidebysig
instance int32 '<Main>b__0_0' (
int32 _,
int32 _
) cil managed
{
// Method begins at RVA 0x2100
// Code size 7 (0x7)
.maxstack 1
.locals init (
[0] int32
) IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005 IL_0005: ldloc.0
IL_0006: ret
} // end of method '<>c'::'<Main>b__0_0'

这说明什么呢? 说明两个参数是真实存在的,但编译器捣了鬼,做了语法上的限制,不让你访问所谓的 _

等等。。。有一个问题,IL中的方法签名怎么是这样的: <Main>b__0_0 (int32 _,int32 _) , 大家应该知道方法签名中不可以出现重复的参数名,比如下面这样定义肯定是报错的。

这说明什么? 说明这个语法糖不仅需要编译器支持,更需要底层的JIT支持,那怎么证明呢?我们用windbg去底层挖一挖。。。为了方便调试,修改如下:


static void Main(string[] args)
{
Func<int, int, int> func = (_, _) =>
{
Console.WriteLine("进入方法体了!!!");
Console.ReadLine();
return 0;
}; var result = func(10, 20);
} 0:000> !clrstack -p
OS Thread Id: 0x52e8 (0)
0000007035F7E5C0 00007ffaff362655 ConsoleApp1.Program+c.b__0_0(Int32, Int32) [C:\5\ConsoleApp1\ConsoleApp1\Program.cs @ 13]
PARAMETERS:
this (0x0000007035F7E600) = 0x000001968000cb48
_ (0x0000007035F7E608) = 0x000000000000000a
_ (0x0000007035F7E610) = 0x0000000000000014

从图中可以看到,虽然都是 _ ,但在线程栈上是完完全全的两个栈地址。 0x0000007035F7E6080x0000007035F7E610

三:总结

总的来说,C#是越来越像函数式编程靠拢,越来越像Scala,就像Jquery的口号一样: Write less,do more。

好了,先就说这两个吧,大家先安装好工具,明天继续解剖~~~


如您有更多问题与我互动,扫描下方进来吧~


C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!(应该是全网第一篇)的更多相关文章

  1. 还学的动吗? 盘点下Vue.js 3.0.0 那些让人激动的功能

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://blog.bitsrc.io/vuejs-3-0-0-beta-features- ...

  2. ES11来了,还学得动吗?

    写在前面 ES2020(即 ES11)上周(2020 年 6 月)已经正式发布,在此之前进入 Stage 4 的 10 项提案均已纳入规范,成为 JavaScript 语言的新特性 一.特性一览 ES ...

  3. Cocos2d-x3.0终于版Mac以及Win系统相关环境部署

    因个人原因此博客停止更新,其它更新博文将在该博客继续更新. http://blog.csdn.net/xiaohan_aimti/article/details/24653831 就在前几天,2014 ...

  4. Creator 2.2.0 终于等来了这款Shader组件神器!一招搞定Effect特效

    先看下视频演示: ShaderHelper2支持Creator 2.2.0 视频录完后才想起,还没在微信小游戏中测试,赶紧试试,下面是在微信开发者工具中的截图. 径向模糊 探照灯 提供了一个Shade ...

  5. [译]ABP v1.0终于发布了!

    ABP v1.0终于发布了! 今天是个大日子!经过约3年的不断开发,第一个稳定的ABP版本,1.0,已经发布了.感谢为该项目做出贡献或试用过的每个人. 立即开始使用新的ABP框架:abp.io/get ...

  6. 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)

    从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ...

  7. 分布式文件系统 FastDFS 5.0.5 & Linux CentOS 7 安装配置(单点安装)——第一篇

    分布式文件系统 FastDFS 5.0.5 & Linux CentOS 7 安装配置(单点安装)--第一篇 简介 首先简单了解一下基础概念,FastDFS是一个开源的轻量级分布式文件系统,由 ...

  8. ShardingSphere你还不会吗?(第一篇)

    ShardingSphere你还不会吗?(第一篇) 作者:星晴(当地小有名气,小到只有自己知道的杰伦粉) 一.需求 我们做项目的时候,数据量比较大,单表千万级别的,需要分库分表,于是在网上搜索这方面的 ...

  9. Truffle 4.0、Geth 1.7.2、TestRPC在私有链上搭建智能合约

    目录 目录 1.什么是 Truffle? 2.适合 Truffle 开发的客户端 3.Truffle的源代码地址 4.如何安装? 4.1.安装 Go-Ethereum 1.7.2 4.2.安装 Tru ...

随机推荐

  1. Django之ORM对象关系模型

    MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需 ...

  2. 模仿 SWPU邮件页面

    模仿SWPU邮件页面 要求 参考swpu 邮件主页,编写一个新闻后台登录页面,并用Js静态验证用户名密码是否为空,用户名为tom 密码为 123跳转到另一个页面 http://mail.swpu.ed ...

  3. 二,表格<table>的使用细节

    如有不足请不吝赐教!最先接触的布局表格,表格灵活性,加载速度都不如<div>灵活,但是对于萌新来说再定位某些,例如div里面套文字,而刚接触html+css又不懂得那么多使用<spa ...

  4. Codeblocks运行按钮变灰,卡程序编译

    实际上,当我们点击绿色运行按钮运行之后,.exe文件会开始运行,当我们点击红色调试按钮之后,会开始调试. 因此当我们在运行卡住之后,点击红色调试按钮,实际上并没有真正的结束程序,只是将窗口隐藏起来,我 ...

  5. Element Form表单实践(下)

    作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e8 ...

  6. 【JAVA习题七】输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

    package erase; import java.util.Scanner; public class 字符串分类 { public static void main(String[] args) ...

  7. [JavaWeb基础] 021.Action中result的各种转发类型

    在struts2中, struts.xml中result的类型有多种,它们类似于struts1中的forward,常用的类型有dispatcher(默认值).redirect.redirectActi ...

  8. node_modules内容太大导致webstrom非常卡

    选中一个文件夹,例如node_modules,点击右键->mark directory as ->excluded,这样就可以把这个文件标记并排除出来,使webstorm不会扫描这个文件下 ...

  9. [apue] 一个工业级、跨平台的 tcp 网络服务框架:gevent

    作为公司的公共产品,经常有这样的需求:就是新建一个本地服务,产品线作为客户端通过 tcp 接入本地服务,来获取想要的业务能力. 与印象中动辄处理成千上万连接的 tcp 网络服务不同,这个本地服务是跑在 ...

  10. Linux(二) 系统远程访问

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1. Why?为什么需要远程访问? 人和人之间对话有两种方式,一种是面对面直接交谈,另一种是打电话. 我 ...