博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 7.1先睹为快(第二部分)
阅读量:7208 次
发布时间:2019-06-29

本文共 2465 字,大约阅读时间需要 8 分钟。

天我们介绍了异步Main函数(Async Main)和默认表达式(Default Expressions)。我们的C# 7.1之旅将继续,今天要介绍的特性在建议中称为推导元组名(Infer Tuple Names)和使用泛型的模式匹配(Pattern-matching with Generics)。

\\

推导元组名(Infer Tuple Names)

\\

虽然开发人员不常考虑到,但是C#中的匿名类型包括了命名推导。例如,编写如下代码时,对象y将具有名为A和B的属性:

\\
\var y = new { x.A, x.B };
\\

根据“推导元组名建议”,值元组基本具有同样的功能。

\\
\var z1 = (A: x.A, B: x.B); //显式名字。\var z2 = (x.A, x.B); //推导名字。
\\

但是匿名类型和值元组间存在着一些显著的差异:

\\
  • 匿名类型需要属性名,属性明可以是显示指定的,也可以是推导得到的。\\t
  • 值元组会将未命名属性标为Item1、Item2等。\\t
  • 如果匿名类型具有重复的名字,那么会产生编译错误。\\t
  • 如果值元组具有重复的显式名字,那么会产生编译错误。\\t
  • 如果值元组具有重复的推导名字,那么推导名会被跳过。例如:(x.A, x.B, y.A)将转化成(Item1, B, Item3)。\\t
  • 值元组不能使用如下保留名字:ToString、Rest、ItemN(N是大于0的数字)。\

C#和VB间有hen一个有意思的差别,VB可以通过函数去推导匿名属性名。例如:

\\
\var y = new { x.A, x.Bar() }; //编译错误\Dim y = New With {x.A, x.Bar()} //匿名类型{A,Bar}\
\\

该功能特性将扩展适用于VB元组。

\\

但如果恰巧有一个扩展方法使用了与推导属性一样的名字,这一特性就会引发破坏性更改。在建议中进一步提出:

\\
\

考虑到这一更改的破坏性有限,并且在C# 7.0中,交付元组的时间窗很短,兼容性委员会认为这种破坏性更改是可以接受的。

\
\\

考虑泛型约束的元组名

\\

如果存在元组名不匹配的问题,那么编译器会尽量警告编程人员。例如:

\\
\public static (int A, int B) Test1((int A, int B) a)\Test1((A: 1, B: 2));\Test1((X: 1, Y: 2)); //给出警告,元组名不匹配。\
\\

如果开始采用泛型约束,代码就不工作了:

\\
\public static T Test2(T a) where T : IEnumerable\u0026lt;(int A, int B)\u0026gt;\Test2(new List\u0026lt;(int A, int B)\u0026gt;());\Test2(new List\u0026lt;(int X, int Y)\u0026gt;()); //没有警告。\
\\

当给出前的解释是,在泛型约束的条件下,编译器是不会去检查元组名的。理论上讲,编译器是可以捕获这类问题的,但是所付出的性能上的代价要远高于所得到的收益。

\\

使用泛型的模式匹配

\\

模式匹配是C# 7.0中新提供的特性。但是使用该特性时,存在。让我们看一下Alex Wiese给出的如下代码:

\\
\class Program\{\    static void Main(string[] args) {}\    public void Send(T packet) where T : Packet\    {\        if (packet is KeepalivePacket keepalive)\        {\            // 使用keepalive的功能代码。\        }\        switch (packet)\        {\            case KeepalivePacket keepalivePacket:\                // 使用keepalivePacket的功能代码。\                break;\        }\    }\}\public class Packet {}\public class KeepalivePacket : Packet {}\
\\

代码会报如下错误:“An expression of type T cannot be handled by a pattern of type KeepalivePacket.”。但如果我们将参数改为System.Object类型,而不是T类型,代码就工作正常了。

\\
\public void Send(object packet)
\\

C# 7.1,通过,修正了这一问题。

\\

我们改进了“模式匹配技术规范”中的一段内容,下面以粗体标出了我们所建议添加的内容:

\\
\

我们认为左侧(left-hand-side)静态类型的特定组合与特定类型是不兼容的,这会导致编译时错误。我们称静态类型E的值与类型T是模式兼容的,如果存在标识转换(Identity Conversion)、隐式引用转换(Reference Conversion)、装箱转换(Boxing Conversion)、显式引用转换,或者存在从E到T的拆箱转换(Unboxing Conversion),或者E或T均为开放类型(Open Type)。如果具有类型E的表达式与其所匹配的类型模式中的类型并不模式兼容,就会产生编译时错误。

\
\\

这被认为是一个软件问题修复问题。由于该更新是“向前不兼容”的,因此只有将编译器设为C# 7.1,才能使用这一更新。

\\

查看英文原文: 

转载地址:http://vclum.baihongyu.com/

你可能感兴趣的文章
桥接模式 - 设计模式学习
查看>>
Google Maps Android API v2 (2)- 地图对象
查看>>
MySQL 5.5 手册下载
查看>>
hdu 1300(dp)
查看>>
POJ 1159 - Palindrome 优化空间LCS
查看>>
CH BR8(小学生放假了-clock()/CLOCKS_PER_SEC-斜率优化常错集锦)
查看>>
N!末尾有多少个零
查看>>
【优先队列】HDU 1873——看病找医生
查看>>
SQL 时间处理
查看>>
HF Reader
查看>>
eclipse项目中关于导入的项目里提示HttpServletRequest 不能引用的解决办法
查看>>
Css 常用属性
查看>>
GRIDVIEW多行多列合并单元格(合并列)
查看>>
sharepoint2010问卷调查(3)-实现问卷的开始和结束时间(采用自定义字段类型)...
查看>>
java final
查看>>
【吐槽】VS2012的安装项目只能用InstallShield Limited Edition
查看>>
win7重装系统时,使用PE工具箱进入系统看到的“C盘变成0.2G,D盘变成48G左右”这是什么回事?...
查看>>
JQuery URL的GET参数值获取方法
查看>>
关于Char* ,CString ,WCHAR*之间的转换问题
查看>>
第十二天--Property List和NSUserDefaults
查看>>