C# 6.0语法新特性体验(二)
之前我在文章通过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.Program和Program本身就是等价的。
需要注意的是,由于C#允许函数重载,因此是存在同名函数的,例如:
static
void foo() { }
static
void foo(int x) { }
这样就存在如下两个问题:
- 转到定义应该跳到那个函数?
- 当对其中的某个函数重命名,另一个函数维持原名称的时候, 使用nameof的地方是否也需要变化?
这两个问题只是体现在VisualStudio上,并不是语法的歧义,也不影响运行结果。在CodePlex中也有专门的文章讨论它,目前的处理方式是:
- 转到定义应该跳到那个函数? (谁先定义转到谁)
- 当对其中的某个函数重命名,另一个函数维持原名称的时候, 使用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语法新特性体验(二)的更多相关文章
- servlet3.0 的新特性之二注解代替了web.xml配置文件
servlet3.0 的新特性: 注解代替了 web.xml 文件 支持了对异步的处理 对上传文件的支持 1.注解代替了配置文件 1.删除了web.xml 文件 2. 在Servlet类上添加@Web ...
- Atitit. c# 语法新特性 c#2.0 3.0 4.0 4.5 5.0 6.0 attilax总结
Atitit. c# 语法新特性 c#2.0 3.0 4.0 4.5 5.0 6.0 attilax总结 1.1. C# 1.0-纯粹的面向对象 1.2. C# 2.0-泛型编程新概念 1.3. ...
- Java8新特性之二:方法引用
上一节介绍了Java8新特性中的Lambda表达式,本小节继续讲解Java8的新特性之二:方法引用.方法引用其实也离不开Lambda表达式. 1.方法引用的使用场景 我们用Lambda表达式来实现匿名 ...
- php5.3到php7.0.x新特性介绍
<?php /*php5.3*/ echo '<hr>'; const MYTT = 'aaa'; #print_r(get_defined_constants()); /* 5.4 ...
- paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较
paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...
- 相比于python2.6,python3.0的新特性。
这篇文章主要介绍了相比于python2.6,python3.0的新特性.更详细的介绍请参见python3.0的文档. Common Stumbling Blocks 本段简单的列出容易使人出错的变动. ...
- Java7语法新特性
Java7语法新特性: 1. switch中增加对String类型的支持. public String generate(String name, String gender) { String ti ...
- [PHP] 从PHP 5.6.x 移植到 PHP 7.0.x新特性
从PHP 5.6.x 移植到 PHP 7.0.x 新特性: 1.标量类型声明 字符串(string), 整数 (int), 浮点数 (float), 布尔值 (bool),callable,array ...
- C# 8.0 的新特性概览和讲解
本文转自 https://blog.csdn.net/hez2010/article/details/84036742 C# 8.0 的新特性概览和讲解 前言 新的改变 可空引用类型(Nullable ...
随机推荐
- postfix导致maillog填满磁盘空间的巨坑!
双休日回家pull在公司修改的代码...于是菜鸟的linux探索之路开始了 1.df -f发现磁盘又占满了(之前是node的error) 2.发现maillog整整10个G,无数条(Jul 7 04: ...
- Sass、Ruby、Nodejs、gulp
1.Sass文件就是普通的文本文件,不过其文件后缀名有两种,一种为“.sass”:另一种为“.scss”.我们一般用“.scss”就好,至于这两种文件扩展名的区别在于“.sass”是Sass语言文件的 ...
- 【STSRM13】花六游鸟小
[题意]给定n个节点的树,每个节点有一个m位二进制数,数字可以随时按位取反,每个数位有一个价值,定义每个点的最大价值是从根到这个点路上的数字(可以取反)或起来的数字中,1有价值0无价值,加起来得到的最 ...
- stdafx.h、stdafx.cpp的作用
这两个文件用于建立一个预编译的头文件".PCH"和一个预定义的类型文件"STDAFX.OBJ".由于MFC体系结构非常大,各个源文件中都包含许多头文件,如果每次 ...
- 列出top中的pid
#!/usr/bin/env python import os import string #方法1:通过字符串的isdigits来判断 #filelist = os.listdir('/proc') ...
- zlib库剖析(1):实现概览
zlib库剖析(1):实现概览 http://blog.csdn.net/zhoudaxia/article/details/8034606 http://blog.chinaunix.net/uid ...
- 全面理解面向对象的 JavaScript(转载)
http://www.ibm.com/developerworks/cn/web/1304_zengyz_jsoo/#resources 前言 当今 JavaScript 大行其道,各种应用对其依赖日 ...
- codevs 1018 [noip 2000 提高] 单词接龙
题目链接:http://codevs.cn/problem/1018/ 题目描述 Description 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, ...
- win 7 浏览器被篡改小插曲
今天下班回家,打开台式机发现IE,火狐都被篡改了.作为运维都会有点强迫症.这是个桌面系统,实在是没兴趣捣鼓.但是还是没办法,经常要用.等我下次有空了,直接换linux好了. 于是开始排查问题吧: 1. ...
- __rb_tree_rebalance
Inline void __rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) //当前节点,根 { x ...