一:背景

1. 讲故事

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

.Net5官方链接

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

新特性预览

2. 安装必备

  • 下载最新的net5 sdk吧:dotnet-sdk-5.0.100-preview.5.20279.10-win-x64.exe

  • 下载最新的 visual studio 2019 preview 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: nopIL_0001: ldsfld class [System.Runtime]System.Func`3<int32, int32, int32> ConsoleApp1.Program/'<>c'::'<>9__0_0'IL_0006: dupIL_0007: brtrue.s IL_0020IL_0009: popIL_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: dupIL_001b: stsfld class [System.Runtime]System.Func`3<int32, int32, int32> ConsoleApp1.Program/'<>c'::'<>9__0_0'IL_0020: stloc.0IL_0021: ldloc.0IL_0022: ldc.i4.s 10IL_0024: ldc.i4.s 20IL_0026: callvirt instance !2 class [System.Runtime]System.Func`3<int32, int32, int32>::Invoke(!0, !1)IL_002b: stloc.1IL_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 hidebysiginstance 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: nopIL_0001: ldc.i4.0IL_0002: stloc.0IL_0003: br.s IL_0005IL_0005: ldloc.0IL_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

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

三:总结

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

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

C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!相关推荐

  1. babel原理_带你了解 snowpack 原理,你还学得动么(下)

    作者:AlienZHOU 转发链接:https://zhuanlan.zhihu.com/p/149351900 目录 带你了解 snowpack 原理,你还学得动么(上) 带你了解 snowpack ...

  2. 重磅!Spring Boot 2.5.0火热发布,还学得动吗?

    今年520的事情是真的多,把Spring Boot 2.5.0的版本发布都给忽略了! 今天跟我一起看看Spring Boot 2.5.0又都带来了哪些振奋人心的新特性吧! 主要更新 支持 Java 1 ...

  3. 微软TypeScript 3.0重磅发布!扶我起来,我还学得动

    web前端教程 用大白话,来讲编程 北京时间7月31日,微软宣布推出 TypeScript 3.0 正式版.TypeScript 3.0 是一个新的里程碑. 官方表示,尽管版本号是一个大变化,但 3. ...

  4. Java 16 正式发布!你还学得动吗?

    就在刚刚,Java 16正式发布. Java 16 正式发布 主要特性 Vector API(孵化) 提升了Java在CPU向量计算的性能,这是对大规模的张量计算的支持,提升了Java在AI领域的能力 ...

  5. Javascript在ES2019中又新增了8个功能!你还学的动么?

    苦逼学习的ES6还没玩溜呢,现在又更新了8个功能,不得不感叹前端在这几年的快速发展. 不过好在,基础夯实之后,再学习新的内容,分分钟的事情. 废话不多说,直接来看这回又更新了些什么幺蛾子. Catch ...

  6. 我年龄大了还学的动it吗

    我有一个朋友是下岗工人,大专学历,今年36岁,生活压力大,以前学了一些软件知识 他现在想进入这一行特别是编程这方面,而且想以此为生,各位兄弟你们说他行吗?如果行该如何学,学些什么? 转载于:https ...

  7. C#9.0 终于来了,带你一起解读 nint 和 Pattern matching 两大新特性玩法

    一:背景 1. 讲故事 上一篇C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!跟大家聊到了Target-typed new 和 Lambda discard parameters,看博客园和 ...

  8. Nutch 2.0 终于来了

    Nutch 2.0 终于来了 ------------------------- 带着大部分人的期待,Nutch 2.0终于发布了,它在Nutch 1.x的基础上做了比较大的改变,主要还是在它的存储层 ...

  9. 鸿蒙系统2.0 评测,鸿蒙2.0终于上机实测 多大内存能跑?

    9月10日的开发者大会上,华为不但带来了EMUI 11,还发布了备受期待的鸿蒙OS 2.0,信息量相当庞大,官方也贴心制作了信息图解. 鸿蒙OS 2.0的口号是"连接无限可能",致 ...

最新文章

  1. scala while循环中断
  2. Node.js模块系统
  3. mysql创建新表失败_MySQL创建表失败的问题
  4. Mysql的timestamp与datetime
  5. 一个4体低位交叉的存储器_GD25Q16CSIG|NRAM存储器的原理及优势是什么?
  6. WEB前端 CSS(非布局)
  7. 你这么爱听歌,一定活得很难过吧 | 今日最佳
  8. 自由口通信模式下计算机读写PLC存储区的程序
  9. 阿里20周年年会散场后,6万人会场无一片垃圾,保洁阿姨都无瓶可捡了
  10. mysql防注入插件_mybatis-plus插件使用的一些问题
  11. mysql 雷同数值连续出现次数_MySql中关于某列中相同数值连续出现次数的统计
  12. hualinux 学生党 建议:读书就是为了社会目标做准备
  13. 电脑关闭Fn键+F1,直接使用F1键
  14. 关于微信双开后,王者荣耀默认只能打开微信主应用问题
  15. C++核心准则边译边学-F.6 如果函数不会抛出异常,则声明为noexcept
  16. 魔域进游戏老是显示服务器繁忙,魔域2014年春节-温情卡诺萨
  17. 朋友圈微信投票很麻烦?python开发个自动化刷票脚本,再也不用头痛了!
  18. 实变函数笔记——对数与基数
  19. pdf 转 高清图片
  20. win10+laravel8+PHP+ElasticSearch+Kibana+高亮 接口搜索

热门文章

  1. MySQL--字符集
  2. Java集合和泛型练习及面试题——博客园:师妹开讲啦
  3. SVN安装和使用总结
  4. k8s extender_Windows Home Server的Drive Extender的9种选择
  5. 如何更改您的iPhone铃声
  6. 停止抱怨英语_停止抱怨垂直视频
  7. android 更改软键盘_如何在Android的Google键盘上更改声音和振动
  8. ccleaner无法更新_CCleaner正在静默更新关闭自动更新的用户
  9. 反射调用 java bean的set和get方法
  10. 软件架构实践文章链接