原文地址:http://www.cnblogs.com/mushroom/archive/2015/07/22/4666113.html#six

2015-07-22 08:29 by 蘑菇先生, 8943 阅读, 56 评论, 收藏, 编辑

阅读目录:

  1. 自动属性默认初始化
  2. 自动只读属性默认初始化
  3. 表达式为主体的函数
  4. 表达式为主体的属性(赋值)
  5. 静态类导入
  6. Null条件运算符
  7. 字符串格式化
  8. 索引初始化
  9. 异常过滤器when
  10. catch和finally代码块内的Await
  11. nameof表达式
  12. 扩展方法
  13. 总结

自动属性默认初始化

使用方法:

public string Name { get; set; } = "hello world";

为了便于理解使用2.0语法展示,编译器生成代码如下:

 public class Customer
{[CompilerGenerated]
private string kBackingField = "hello world";
public Customer()
{
this.kBackingField = "hello world";
}public string Name
{[CompilerGenerated]get{return this.<Name>k__BackingField;}[CompilerGenerated]set{this.<Name>k__BackingField = value;}
}
} 

从生成代码中可以看出编译器是在实例构造函数时,初始化属性信息的。

自动只读属性默认初始化

使用方法:

public string Name1 { get; } = "hello world";

编译器生成代码如下:

[CompilerGenerated]
private readonly string kBackingField;
public Customer()
{this.kBackingField = "hello world";}
public string Name1
{[CompilerGenerated]
get { return this.k__BackingField; }}

由于初始化默认值实在构造函数中赋值的,所以跟属性只读没关系。

表达式为主体的函数

使用方法:

Body Get(int x, int y) => new Body(1 + x, 2 + y);

编译器生成如下:

private Program.Body Get(int x, int y)
{return new Program.Body(1 + x, 2 + y);
}

简化了单行方法的编写,省去写大括号的功夫。

同时支持没有返回值的写法:

void OutPut(int x, int y) => Console.WriteLine("hello world");

也支持异步函数的编写:

async void OutPut(int x, int y) => await new Task(() => Console.WriteLine("hello wolrd"));

表达式为主体的属性(赋值)

使用方法:

public string Name2 => "hello world";

编译器生成代码如下:

public string Name2
{
get { return "mushroomsir"; }}

编译器只生成了个只读属性。

静态类导入

这个特性可以一次性导入某类型的所有静态成员,使静态成员在后面的代码中没有类型限制直接使用,像使用本类型下面的静态方法一样。

using static System.Console;class Program {
static void Main(string[] args)
{WriteLine("hello wolrd");
}
}

编译器生成代码如下:

private static void Main(string[] args){Console.WriteLine("hello wolrd");
}

省去了类型名称的重复编写。

Null条件运算符

使用方法:

Customer customer = new Customer(); string name3 = customer?.Name;

等同于:

Customer customer = new Customer();
if (customer1 != null)
{string name = customer1.Name;
}

可以和??组合起来使用:

if (customer?.Face2()??false)

还可以2个一起用:

int? Length = customer?.Name?.Length;

也可以方法调用:

customer?.Face();

这个语法糖的目的是在对象使用前检查是否为null。如果对象为空,则赋值给变量为空值,所以例子中需要一个可以为空的int类型、即int?。

如果对象不为空,则调用对象的成员取值,并赋值给变量。

字符串格式化

String.Format有些不方便的地方是:必须输入"String.Format",使用{0}占位符、必须顺序来格式化、这点容易出错。

var s = String.Format("{0} is {1} year {{s}} old", p.Name, p.Age);

新的语法糖使用起来相对更轻松些:

var s = $"{p.Name} is {p.Age} year{{s}} old";

编译器生成如下,和之前没有区别:

var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);

有趣的是,新格式化方式还支持任何表达式的直接赋值:

var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

索引初始化

List虽然这样写可以编译通过,但是会抛异常的,使用方法:

var numbers = new List<string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };

编译器生成代码如下:

List list = new List();
list[7] = "seven";list[9] = "nine";
list[13] = "thirteen";

Dictionary可以执行,因为二者内部索引机制不一样:

 var numbers = new Dictionary<int, string> {[7] = "seven",[9] = "nine",[13] = "thirteen" };

编译器生成代码:

 Dictionary<int, string> dictionary2 = new Dictionary<int, string>();dictionary2[7] = "seven";dictionary2[9] = "nine";dictionary2[13] = "thirteen";Dictionary<int, string> dictionary = dictionary2;

异常过滤器when

使用方法:

 try
{
throw new ArgumentException("string error");}catch (ArgumentException e) when (myfilter(e)){
Console.WriteLine(e.Message);}static bool myfilter(ArgumentException e){
return false;}

When语法作用是:在进入到catch之前、验证when括号里myfilter方法返回的bool,如果返回true继续运行,false不走catch直接抛出异常。

使用这个filter可以更好的判断一个错误是继续处理还是重新抛出去。按照以前的做法,在catch块内如需再次抛出去,需要重新throw出去,这时的错误源是捕捉后在抛的,而不是原先的,有了when语法就可以直接定位到错误源。

catch和finally代码块内的Await

Await异步处理是在c#5.0提出的,但不能在catch和finally代码块内使用,这次在C#6.0更新上支持了。

使用方法:

    async void Solve(){try{await HttpMethodAsync();}catch (ArgumentException e){await HttpMethodAsync();}finally{await HttpMethodAsync();}}

编译器把catch和finally的await生成到状态机里面的MoveNext()里面。原来里面只有 TaskAwaiter,现在多了2个。状态机里面的代码和原先的一样,只是更复杂了下,有兴趣的童鞋可以先看下Async、Await剖析再去深究。

nameof表达式

使用方法:

string name = "";
Console.WriteLine(nameof(name));

控制台输出 "name"。

有时候会需要程序中一些成员的字符串名称,比如抛出ArgumentNullException异常的时候,想知道ArgumentNullException类型的字符串名称,这时候就可以用nameof获取字符

串“ArgumentNullException”。现在做法都是手动复制一下,但重构改名的时候容易忘记变更字符串,使用nameof就可以避免了。

当如下使用的时候,编译器会只取最后的ZipCode。

nameof(person.Address.ZipCode)

编译器生成如下代码:

Console.WriteLine("name");

扩展方法

    using static System.Linq.Enumerable; //引入类型,而不是命名空间class Program{static void Main(){var range = Range(5, 17);                // Ok: 不是扩展方法var odd = Where(range, i => i % 2 == 1); // Error, 不在全局作用域里var even = range.Where(i => i % 2 == 0); // Ok}}

首先Enumerable是个静态类,里面是各种扩展方法,比如range。static的作用是把类型的静态成员一次性导入,rang虽然是静态方法,但不能导入,比如where。

因为扩展方法虽然是一个静态方法,但是语法规定它作为一个实例方法使用(打点),所以不能在全局作用域里当静态方法用,因此var odd = Where(range, i => i % 2 == 1)是错误的。

但是static却能把类型的扩展方法作为扩展方法本身角色的功能导入进去,所以var even = range.Where(i => i % 2 == 0)是ok的。

这里可能稍微有点绕,lz尽量写清楚,static新用法有2个功能:

  1. 把静态成员导入,但扩展方法比较特殊、排除在外。这时static是c# 6.0的新功能。
  2. 等同于把扩展方法的命名空间导入,所以在集合上可以打点调用扩展方法。这是之前就有的功能,而不是把扩展方法转成单纯的静态方法导入使用。

总结

看到园子里有介绍的文章,一时来兴趣了,下班后安装个社区版就研究分享下。 虽然微软一直出新东西,但都是由下至上迭代的,所以学习起来是非常快的。

参考https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#expression-bodied-function-members

探索C#之系列导航

作者:蘑菇先生 出处:http://mushroom.cnblogs.com/

本文版权归作者和博客园共有,欢迎转载。未经作者同意下,必须在文章页面明显标出原文链接及作者,否则保留追究法律责任的权利。
如果您认为这篇文章还不错或者有所收获,可以点击右下角的【推荐】按钮,因为你的支持是我继续写作,分享的最大动力

探索C#之6.0语法糖剖析相关推荐

  1. vue3.0语法糖及ref、reactive、toRef、toRefs的区别

    vue3.0语法糖 前几天一个月薪35k的兄弟,给我推了一个人工智能学习网站,看了一段时间挺有意思的.包括语音识别.机器翻译等从基础到实战都有,很详细,分享给大家. 1.什么是setup语法糖 起初 ...

  2. 看看C# 6.0中那些语法糖都干了些什么(终结篇)

    终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...

  3. 看看C# 6.0中那些语法糖都干了些什么(上篇)

    一:自己主动初始化属性 确实这个比之前的版本号简化了一下.只是你肯定非常好奇.究竟编译器给我们做了哪些东西呢? 1 class Student 2 { 3 public string Name { g ...

  4. mysql8 create table 语法错误_MySQL8.0 Window Function 剖析

    title: $MySQL8.0 Window Functions 剖析 author: $马腾 什么是window function window function 是在满足某种条件的记录集合上执行 ...

  5. C# 中居然也有切片语法糖,太厉害了

    一:背景 1. 讲故事 昨天在 github 上准备找找 C# 9 又有哪些新语法糖可以试用,不觉在一个文档上看到一个很奇怪的写法:  foreach (var item in myArray[0.. ...

  6. 小哥哥小姐姐,来尝尝 Async 函数这块语法糖

    编者注:众所周知,JS 最大的特性就是异步,异步提高了性能但是却给我们编写带来了一定困难,造就了令人发指的回调地狱.为了解决这个问题,一个又一个的解决方案被提出来.今天我们请来了 <JavaSc ...

  7. Java 中的语法糖,真甜。

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 我们在日常开发中经常会使用到诸如泛型.自动拆箱和装箱.内部 ...

  8. Jvm 系列(十一)Java 语法糖背后的真相

    语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是,在计算机语言中添加某种语法,这些语法糖虽然不会对语言 ...

  9. C#语法糖(Csharp Syntactic sugar)大汇总

    首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...

最新文章

  1. 学完 CompletionService,可以做时间管理大师?
  2. IE6,7,8中兼容css3圆角问题
  3. Javascript跨域访问解决方案
  4. 蓝绿发布、滚动发布、灰度发布,有什么区别?
  5. 数据库mysql中贴换函数_关于一个自定义MYSQL函数,实现点击链接后,在数据库里改变数据的问题。...
  6. jQuery UI基础 学习笔记
  7. Flutter RichText 使用案例解析 Flutter WidgetSpan 设置图片显示
  8. LeetCode-69 x的平方根
  9. 聚焦2016:关于语音识别、图像识别及大数据
  10. VM虚拟机里安装Centos
  11. android studio不显示标题,Android Studio:活动预览不显示标题栏
  12. python在电力系统中的应用_PyPSA在电力系统潮流计算中的应用
  13. 奶瓶 linux内核,CDlinux专用inflator-打气筒(reaver的图形化,beini奶瓶作者编写)下载 - 无线安全新手入门 - 无线论坛...
  14. 什么是实体关系图(ERD)?
  15. Java小游戏练习---超级玛丽代码实现
  16. 微信小程序获取年月日周及早上、中午、晚上
  17. CAD——MV视口与图层
  18. php极简wiki,Wiki.js初体验
  19. WWW2021论文速递:细粒度城市流量预测
  20. AC 瘦AP配置 ensp

热门文章

  1. 一直处于building “XXX”gradle project info
  2. 流处理开源框架Flink原理简介和使用
  3. 优秀软件架构师成长之路
  4. linux下tcpdump的使用简介
  5. 如何优雅地关闭Kubernetes集群中的Pod
  6. 《Go 语言程序设计》读书笔记 (三) 方法
  7. 在Golang中使用Protobuf
  8. kafka中生产者和消费者的分区问题
  9. 关于mysql的几个问题
  10. JVM类加载机制详解