一:背景
1. 讲故事
好消息,.NET 5.0
终于在2020年6月10日发布了第五个预览版,眼尖的同学一定看到了在这个版本中终于支持了 C# 9.0
,此处有掌声,太好了!!!.net 5的推出,.net core就会淡出了。
可以看到目前的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: 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:5ConsoleApp1ConsoleApp1Program.cs @ 13] PARAMETERS: this (0x0000007035F7E600) = 0x000001968000cb48 _ (0x0000007035F7E608) = 0x000000000000000a _ (0x0000007035F7E610) = 0x0000000000000014
从图中可以看到,虽然都是 _
,但在线程栈上是完完全全的两个栈地址。 0x0000007035F7E608
和 0x0000007035F7E610
。
三:总结
总的来说,C#是越来越向函数式编程靠拢,越来越像Scala,就像Jquery的口号一样: Write less,do more。
好了,先就说这两个吧,大家先安装好工具,明天继续解剖C# 9.0 新功能。
本文转自博客园,原标题:C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!(应该是全网第一篇),
原文链接:https://www.cnblogs.com/huangxincheng/p/13097256.html
【江湖人士】(jhrs.com) 投稿作者:IT菜鸟,不代表江湖人士立场,如若转载,请注明出处:https://jhrs.com/2020/37060.html
扫码加入电报群,让你获得国外网赚一手信息。
文章标题:C#9.0 新特性研究,全网第一篇