码迷,mamicode.com
首页 > 其他好文 > 详细

C# 6.0语法新特性体验(二)

时间:2014-08-21 22:34:14      阅读:337      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   io   strong   

之前我在文章通过Roslyn体验C# 6.0的新语法中介绍了一些C# 6.0的语法特性,现在随着Visual Studio 14 CTP3的发布,又陆续可以体验一些新的特性了,这里简单的介绍一下之前没有介绍的新语法。

属性表达式(Property Expressions)

我们常常会在类中写一些通过函数生成的只读属性:

????class Point
????{
????????public int X { get; set; }
????????public int Y { get; set; }

????????public Point(int x, int y)
????????{
????????????this.X = x;
????????????this.Y = y;
????????}

????????
public double Distance
????????{
????????????get { return Math.Sqrt((X * X) + (Y * Y)); }
????????}

????????
public Point Move(int dx, int dy)
????????{
????????????return new Point(X + dx, Y + dy);
????????}
????}

现在,可以利用一个Lambda表达式简化这一过程:

????????public double Distance => Math.Sqrt((X * X) + (Y * Y));

?

函数表达式(Method Expressions)

函数表达式和属性表达式比较类似,使得我们可以通过Lambda表达式简化成员函数。还是以上面的Point为例,Move函数可以简化如下

????????public Point Move(int dx, int dy) => new Point(X + dx, Y + dy);

最后,再总结前文介绍的几个新特性来一起来简化Point类:

????class Point(int x, int y)
????{
????????public int X { get; set; } = x;
????????public int Y { get; set; } = y;

????????public double Distance => Math.Sqrt((X * X) + (Y * Y));

????????public Point Move(int dx, int dy) => new Point(X + dx, Y + dy);
????}

?

?

NULL检查运算符(Monadic null checking)

这个是我非常喜欢的一个语法,例如我们要获取一个Point序列的第一个点的X坐标,第一感觉会这么写:

????int firstX = points.First().X;

但是,老鸟会告诉你,这儿没有进行NULL检查,正确的版本是这样的:

????int? firstX = null;
????if (points != null)
????{
????????var first = points.FirstOrDefault();
????????if (first != null)
????????????firstX = first.X;
????}

正确倒是正确了,代码取变得难读多了。现在,在C# 6.0中,引入了一个 ?. 的运算符,前面的代码可以改成如下形式:

????int? firstX = points?.FirstOrDefault()?.X;

从这个例子中我们也可以看出它的基本用法:如果对象为NULL,则不进行后面的获取成员的运算,直接返回NULL

需要注意的是,由于"?."运算符返回的可以是NULL,当返回的成员类型是struct类型的时候,"?."和"."运算符的返回值类型是不一样的。

????Point p = new Point(3, 2);

????Console.WriteLine(p.X.GetType() == typeof(int));????????//true
????Console.WriteLine(p?.X.GetType() == typeof(int?));????????//true

另外,除了"?."运算符外,还有一个"?[]"运算符,以使得我们可以写出如下表达式:

????int? first = customers?[0].Orders.Count();

?

nameof表达式(Nameof expressions)

我们常常在反射或类似的技术中以字符串的形式使用属性的名称,抛开拼写错误不谈,当我们进行重构而修改属性名称的时候,由于字符串类型的属性得不到编译器检查,修改相应的字符串属性名称是一件非常令人头痛的事情,现在有了nameof,再也不用担心拼错属性名称了。

nameof运算符可以作用于变量、函数、类以及名字空间中,用于返回返回其名称,例如:

????static void Main(string[] args)
????{
????????Console.WriteLine(nameof(Main));????????//
输出 "Main"
????}

当其参数是由"."运算符拼接起来的时候,只返回最后的名称,例如:

????Console.WriteLine(nameof(ConsoleApplication1.Program));????????//输出 "Program"

这个也可以理解,因为ConsoleApplication1.ProgramProgram本身就是等价的。

需要注意的是,由于C#允许函数重载,因此是存在同名函数的,例如:

????static void foo() { }
????static void foo(int x) { }

这样就存在如下两个问题:

  1. 转到定义应该跳到那个函数?
  2. 当对其中的某个函数重命名,另一个函数维持原名称的时候, 使用nameof的地方是否也需要变化?

这两个问题只是体现在VisualStudio上,并不是语法的歧义,也不影响运行结果。在CodePlex中也有专门的文章讨论它,目前的处理方式是:

  1. 转到定义应该跳到那个函数? ????(谁先定义转到谁)
  2. 当对其中的某个函数重命名,另一个函数维持原名称的时候, 使用nameof的地方是否也需要变化? (重命名函数不重命名nameof,其它的类型如属性等重命名会一起变化)

?

catch和finally语句块中支持await

在C# 5.0中引入了await运算符,可以方便我们执行异步运算。当时其并不能在catch和finally中使用,让人有点意犹未尽的感觉。在C# 6.0放开了这一限制,使用更加方便了。

????try
????{
????????res = await Resource.OpenAsync(…);
????}
????catch (ResourceException e)
????{
????????await Resource.LogAsync(res, e);????//
现在支持了
????}
????finally
????{
????????if (res != null) await res.CloseAsync(); //
现在也支持了
????}

?

catch支持筛选条件了

catch支持筛选条件也是呼声比较高的特性之一,现在终于可以省得重新再抛一次了

????try
????{
????????foo();
????}
????catch (Exception e ) if (e.HResult == 0x800000C)
????{
????????//do something
????}

?

其它未支持的特性

我这里只是介绍目前可以使用的新特性,我这里试出来的貌似可以补充的就这么多了。其它还有一些尚未推出的特性等下次有了更新的版本再做介绍。感兴趣的朋友可以看看官方的特性实现状态文档:http://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Home。目前比较期待的新特性是String interpolation模式匹配,尤其是模式匹配,希望能早日体验一下。

另外,目前还没有发现什么BCL方面的更新介绍,虽然BCL已经比较完善了,但感觉这次更新粒度蛮大的,估计至少会有一些基础库的补充的。

C# 6.0语法新特性体验(二),布布扣,bubuko.com

C# 6.0语法新特性体验(二)

标签:style   blog   http   color   使用   os   io   strong   

原文地址:http://www.cnblogs.com/TianFang/p/3928172.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!