在之前的C# 7 新特性博客中,我们谈到了Tuples,Record Type和Pattern Matching。这些都是C#新特性中最可能出现的。在本博客中,我们会提到更多的一些特性,虽然这些特性不像之前的有那么多的关注,但也是很有用的特性。

来源https://www.kenneth-truyers.net/2016/01/25/new-features-in-c-sharp-7-part-2/?utm_campaign=C%23%2BWeekly&utm_medium=email&utm_source=C%23_Weekly_44

Non-nullable引用类型##

What###

c#2.0中引入了可空值类型,本质上它是Nullable类的语法糖。而Non-nullable是这种特性的逆特性。它可以允许你声明一个保证不可为null的引用类型。

Why###

空引用一直被称之为"The billion dollar mistake"(Tony Hoare)。NullReference异常太常见了。问题是有两方面的,要么你没有检测null值,造成运行时异常;要么你检查了他们,你的的代码变成了垃圾堆,充斥着检测null的代码,而却缺少真正需要的语句。声明一个不可为null的引用类型可以克服这个问题。

How###

注意:下面的语法是尚未确定下来的,仍可能变动。目前有各种各样的提议,所以不清楚具体的形式会是什么样子。当我提到"error"时,尚不清楚是兼容性错误还是只是warning。

首先,最理想的做法是,引用类型默认为Non-nullable的,这样可以和值类型的默认也是Non-nullable相对应,如下。

int a;     //non-nullable value type
int? b; //nullable value type
string c; //non-nullable reference type
string? d; //nullable reference type

然而,这种做法兼容性非常不好。之前存在的数百万千万行代码,会因为引用类型默认为Non-nullable而break。所以必须使用不同的方式,以满足向前兼容。目前提议的做法如下。

int a;     //non-nullable value type
int? b; //nullable value type
string! c; //non-nullable reference type
string d; //nullable reference type

使用nullbale类型和Non-nullable类型会影响编译器。

MyClass a;  // Nullable reference type
MyClass! b; // Non-nullable reference type a = null; // OK, this is nullable
b = null; // Error, b is non-nullable
b = a; // Error, n might be null, s can't be null WriteLine(b.ToString()); // OK, can't be null
WriteLine(a.ToString()); // Warning! Could be null! if (a != null) { WriteLine(a.ToString); } // OK, you checked
WriteLine(a!.Length); // Ok, if you say so

这种语法兼容性是没问题的,但是对于泛型却会有问题。

/ The Dictionary is non-nullable but string, List and MyClass aren't
Dictionary<string, List<MyClass>>! myDict; // Proper way to declare all types as non-nullable
Dictionary<string!, List<MyClass!>!>! myDict;

如上,却不便于阅读。一种简便的形式如下。

// Typing ! in front of the type arguments makes all types non-nullable
Dictionary!<string, List<MyClass>> myDict;

局域函数local functions##

What###

允许你在区域作用域内声明方法和类型。

Why###

通过Func和Action匿名方法在一定程度上可以这么做。但是这样缺少一些特性,如下

  • 泛型
  • **ref和out参数
  • params

How###

public int Calculate(int someInput)
{
int Factorial(int i)
{
if (i <= 1)
return 1;
return i * Factorial(i - 1);
}
var input = someInput + ... // Other calcs return Factorial(input);
}

不可变类型##

What###

不可变对象是在对象创建之后,其状态不能被修改。

Why###

不可变对象有如下好处:

  • 天生的线程安全
  • 更容易使用和推测代码
  • 更方便并行编程
  • 不可变类型可以缓存,因为他们不会改变

目前,也是有可能去声明不可变对象的,如下

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

如上虽然声明定义了不可变对象,但是其意图却是不明显的。也许某一天有人对其添加了setter,那对其他的使用者来说,就会有不一样的结果。

How###

注意:再一次说明,如下语法是尚未固定的。初始的提案是添加immutable关键字。

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

当有了不可变类型之后,在语言上就可以支持基于不同的一个实例来创建一个新的实例,如下。

var a = new Point(2, 5);
var b = a with { X = 1};

总结##

如上所述,仍是C# 7的早期阶段,如上语法很有可能会变。但是这些特性非常令人exciting的,也会使C#编程变得更愉悦。鼓励大家去Github上去看有关特性的目前的讨论情形。

C# 7 新特性-2的更多相关文章

  1. SQL Server 2014 新特性——内存数据库

    SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...

  2. ElasticSearch 5学习(10)——结构化查询(包括新特性)

    之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...

  3. [干货来袭]C#6.0新特性

    微软昨天发布了新的VS 2015 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下也是昨天发布的新的C#6.0的部分新特性吧.. ...

  4. CSS3新特性应用之结构与布局

    一.自适应内部元素 利用width的新特性min-content实现 width新特性值介绍: fill-available,自动填充盒子模型中剩余的宽度,包含margin.padding.borde ...

  5. 【译】Meteor 新手教程:在排行榜上添加新特性

    原文:http://danneu.com/posts/6-meteor-tutorial-for-fellow-noobs-adding-features-to-the-leaderboard-dem ...

  6. 跨平台的 .NET 运行环境 Mono 3.2 新特性

    Mono 3.2 发布了,对 Mono 3.0 和 2.10 版本的支持不再继续,而且这两个分支也不再提供 bug 修复更新. Mono 3.2 主要新特性: LLVM 更新到 3.2 版本,带来更多 ...

  7. Atitit opencv版本新特性attilax总结

    Atitit opencv版本新特性attilax总结 1.1. :OpenCV 3.0 发布,史上功能最全,速度最快的版1 1.2. 应用领域2 1.3. OPENCV2.4.3改进 2.4.2就有 ...

  8. es6 新特性2

    es6其他几个非常有用的新特性. import export 这两个家伙对应的就是es6自己的module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成 ...

  9. ES6 新特性

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...

  10. 谈谈我的微软特约稿:《SQL Server 2014 新特性:IO资源调控》

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 撰写经历(Experience) 特约稿正文(Content-body) 第一部分:生活中资源 ...

随机推荐

  1. [vue-router] Failed to resolve async component default: Error: Loading chunk 0 failed.

    在整合laravel5.4 和vue2.1的时候遇到一个奇怪的问题 Uncaught SyntaxError: Unexpected token < Error: Loading chunk 0 ...

  2. 时间模块(time/date)

    在Python中,常用的表示方式的时间有:时间戳,字符串时间,元组时间(既年,月,日,时,分,秒,周几,一年中的第几天,时区)     time模块:   time.timezone: 获取当前标准时 ...

  3. libyuv编译【转】

    转自:http://blog.csdn.net/kl222/article/details/41309541 版权声明:本文为博主原创文章,未经博主允许不得转载. 下载代码(要FQ): git clo ...

  4. Oracle rman 脚本

    1.shell脚本1)vi rman_backup.cmd#rman_backup.cmdconnect target /run{  allocate channel d1 device type d ...

  5. 【bzoj1086】王室联邦

    我以为树分块什么的必有高论,结果居然是个暴力…… 方法也很简单,我看下每个节点dfs的时候是否已经大于k个,大于的话我就新开一块. 注意dfs的时候当前节点不能放进子树的块中. #include< ...

  6. 最小生成树Prim算法Kruskal算法

    Prim算法采用与Dijkstra.Bellamn-Ford算法一样的“蓝白点”思想:白点代表已经进入最小生成树的点,蓝点代表未进入最小生成树的点. 算法分析 & 思想讲解: Prim算法每次 ...

  7. Java上传文件格式判断

    判断用户上传文件的合法性仅仅通过后缀名是完全不够的,谁也不知道后缀名是否被更改,服务器保存一个不知道真实类型的文件有极大的风险. 因此需要后台进行进一步的文件类型校验,这里有两种情况: 1)一般的文件 ...

  8. python中的enumerate使用

    enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量,如 字符串,列表等 一般情况下对一个列表或数组既要遍历索引又要遍历元素时, ...

  9. 使用CreateRemoteThread把代码远程注入指定exe执行

    由于本人也是新手,如果有朋友不懂windows api相关知识,我相信查阅书籍或者百度会比我说有帮助的多,下面就我所做简单复述一下过程,欢迎指正缺点. 效果图示如下: 做的这个例子首先是创建了一个MF ...

  10. 如何在windows平台下使用hsdis与jitwatch查看JIT后的汇编码

    1. 安装hsids 这一步比较麻烦,需要提前安装cygwin,以及下载openjdk的源码 具体步骤请参考下面的两篇文章 How to build hsdis-amd64.dll and hsdis ...