1:背景1.讲故事。NET5终于在前天的2020-08-25发布了第八个预览版,太多的预览让我麻木了,C#9又加入了更多的新特性。既然我还想留在这条船上,我还得继续努力学习。本文就和大家聊聊几个新的关键词。二:新的关键字1.init出来了一个新的语法糖。首先要做的是揭开它的老底,这样就很容易推测出它的应用场景。为了表述方便,我先举个例子:publicclassPerson{publicstringName{get;init;}}乍一看有点乱,没关系,我们先用ILSpy看看,如图下图:上图已经解释的很清楚了。事实证明,init会自动为私有只读字段生成一个包。对于readonly,相信大家已经很熟悉了。初始化只有两种方式:声明时和构造函数中,但是从C#9开始,多了一个属性赋值方式,也就是说现在有三种赋值方式。恢复代码如下:publicclassPerson{privatereadonlystringname;publicstringName{get=>name;init{name=value;}}}这个方法如果改成之前的方法肯定会报错,如下图:需要注意的是,编译器也做了特殊的限制。允许在类初始化器中使用,不允许单独取出来赋值,如下图:所以一般情况下,init的作用就是给你增加一个初始化read的方法-只有字段,仅此而已。2.record为了方便演示,我先上传一段代码,如下图:publicrecordPerson{publicstringName{get;放;}publicintAge{得到;;是的,除了class、struct、enum、delegate,还有一个记录,我们的C#越来越强大了。还是老规范,用ILspy看底层生成了个啥,如下代码所示:publicclassPerson:IEquatable{protectedvirtualTypeEqualityContract=>typeof(Person);公共字符串名称{得到;放;}publicintAge{得到;放;}publicvirtualPerson<>Clone(){returnnewPerson(this);}publicoverrideintGetHashCode(){return(EqualityComparer.Default.GetHashCode(EqualityContract)*-1521134295+EqualityComparer.Default.GetHashCode(Name))*-1521134295+EqualityComparer.Default.GetHashCode(Age);}publicoverrideboolEquals(object?obj){returnEquals(objasPerson);}publicvirtualboolEquals(Person?P_0){returnP_0!=null&&(object)EqualityContract==P_0!.EqualityContract&&EqualityComparer.Default.Equals(Name,P_0!.Name)&&EqualityComparer.Default.Equals(Age,P_0!.年龄);}protectedPerson(PersonP_0){Name=P_0.Name;年龄=P_0.年龄;}publicPerson(){}boolIEquatable.Equals(Personother){returnEquals(other);}}从ILspy查看生成的代码,我们可以发现两条信息:记录也是一个类,重写了对象中的一些方法如GetHashCode、Equals等,根据字段比较判断类是否相等在课堂里。说到根据字段判断类是否相等,不知道大家有没有似曾相识的感觉?不管怎样,它让我想起了匿名类型,因为它生成的C#代码和record是一模一样的。如果你不相信我,让我告诉你。varperson=new{Name="jack",Age=20};接下来看看是不是真的是逐场对比。代码如下图所示:staticvoidMain(string[]args){varperson=newPerson(){Name="jack",Age=20};varperson2=newPerson(){Name="jack",Age=20};varb=person.Equals(person2);你肯定有一些疑问:1)为什么要实现IEquatable接口?这是因为当Person是泛型类型T时,默认的publicoverrideboolEquals(object?obj)被避免了。这是一个高性能的双箱操作,效率太低了。深入研究可以看我的博文:https://www.cnblogs.com/huangxincheng/p/12996361.html。2)为什么有equals而没有==?这是一个很好的问题。谁知道C#开发团队的想法。按照现在的情况,如果用==和equals来比较两个对象,结果肯定是不一样的。我想你可以理解,毕竟一个是引用,一个是按字段比较,比较坑爹,如下图:3)<>Clone()方法的作用是什么从从方法体来看,这个方法是用来做浅拷贝的,但是方法名前面有一对<>,表示是为了防止你直接调用它。那么问题来了,怎么调用呢?这涉及到一个新的语法糖。3.with的语法糖也挺🐂👃,就是帮你调用record的<>clone方法,不信请上传代码。staticvoidMain(string[]args){varperson=newPerson(){Name="jack",Age=20};varperson2=有{}的人;}然后看IL反编译后的代码但是我也有一个疑问,为什么要阻止我直接调用Clone方法呢?新东西,不知道应用场景,谁能搞定~~~😂😂😂4:总结总的来说C#越来越新奇,一直践行着jquery的口号:writeless,domore。有一点要提醒的是语法糖太多了,一定要知道是什么,不要常年在编译器里迷路。二维码关注。转载本文,请联系一线码农,聊聊技术公众号。
