C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!
一:背景
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一起解读吧!相关推荐
- babel原理_带你了解 snowpack 原理,你还学得动么(下)
作者:AlienZHOU 转发链接:https://zhuanlan.zhihu.com/p/149351900 目录 带你了解 snowpack 原理,你还学得动么(上) 带你了解 snowpack ...
- 重磅!Spring Boot 2.5.0火热发布,还学得动吗?
今年520的事情是真的多,把Spring Boot 2.5.0的版本发布都给忽略了! 今天跟我一起看看Spring Boot 2.5.0又都带来了哪些振奋人心的新特性吧! 主要更新 支持 Java 1 ...
- 微软TypeScript 3.0重磅发布!扶我起来,我还学得动
web前端教程 用大白话,来讲编程 北京时间7月31日,微软宣布推出 TypeScript 3.0 正式版.TypeScript 3.0 是一个新的里程碑. 官方表示,尽管版本号是一个大变化,但 3. ...
- Java 16 正式发布!你还学得动吗?
就在刚刚,Java 16正式发布. Java 16 正式发布 主要特性 Vector API(孵化) 提升了Java在CPU向量计算的性能,这是对大规模的张量计算的支持,提升了Java在AI领域的能力 ...
- Javascript在ES2019中又新增了8个功能!你还学的动么?
苦逼学习的ES6还没玩溜呢,现在又更新了8个功能,不得不感叹前端在这几年的快速发展. 不过好在,基础夯实之后,再学习新的内容,分分钟的事情. 废话不多说,直接来看这回又更新了些什么幺蛾子. Catch ...
- 我年龄大了还学的动it吗
我有一个朋友是下岗工人,大专学历,今年36岁,生活压力大,以前学了一些软件知识 他现在想进入这一行特别是编程这方面,而且想以此为生,各位兄弟你们说他行吗?如果行该如何学,学些什么? 转载于:https ...
- C#9.0 终于来了,带你一起解读 nint 和 Pattern matching 两大新特性玩法
一:背景 1. 讲故事 上一篇C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!跟大家聊到了Target-typed new 和 Lambda discard parameters,看博客园和 ...
- Nutch 2.0 终于来了
Nutch 2.0 终于来了 ------------------------- 带着大部分人的期待,Nutch 2.0终于发布了,它在Nutch 1.x的基础上做了比较大的改变,主要还是在它的存储层 ...
- 鸿蒙系统2.0 评测,鸿蒙2.0终于上机实测 多大内存能跑?
9月10日的开发者大会上,华为不但带来了EMUI 11,还发布了备受期待的鸿蒙OS 2.0,信息量相当庞大,官方也贴心制作了信息图解. 鸿蒙OS 2.0的口号是"连接无限可能",致 ...
最新文章
- scala while循环中断
- Node.js模块系统
- mysql创建新表失败_MySQL创建表失败的问题
- Mysql的timestamp与datetime
- 一个4体低位交叉的存储器_GD25Q16CSIG|NRAM存储器的原理及优势是什么?
- WEB前端 CSS(非布局)
- 你这么爱听歌,一定活得很难过吧 | 今日最佳
- 自由口通信模式下计算机读写PLC存储区的程序
- 阿里20周年年会散场后,6万人会场无一片垃圾,保洁阿姨都无瓶可捡了
- mysql防注入插件_mybatis-plus插件使用的一些问题
- mysql 雷同数值连续出现次数_MySql中关于某列中相同数值连续出现次数的统计
- hualinux 学生党 建议:读书就是为了社会目标做准备
- 电脑关闭Fn键+F1,直接使用F1键
- 关于微信双开后,王者荣耀默认只能打开微信主应用问题
- C++核心准则边译边学-F.6 如果函数不会抛出异常,则声明为noexcept
- 魔域进游戏老是显示服务器繁忙,魔域2014年春节-温情卡诺萨
- 朋友圈微信投票很麻烦?python开发个自动化刷票脚本,再也不用头痛了!
- 实变函数笔记——对数与基数
- pdf 转 高清图片
- win10+laravel8+PHP+ElasticSearch+Kibana+高亮 接口搜索