本文转自 https://blog.csdn.net/hez2010/article/details/84036742
该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/1037 访问。
2018年11月12日微软在 MSDN 博客的 Building C# 8.01 一文发表了新的 C# 8.0 即将发布的特性,现在让我们来看一下。
从此,引用类型将会区分是否可分,可以从根源上解决 NullReferenceException。但是由于这个特性会打破兼容性,因此没有当作 error 来对待,而是使用 warning 折衷,而且开发人员需要手动 opt-in 才可以使用该特性(可以在项目层级或者文件层级进行设定)。
例如:
string s = null; // 产生警告: 对不可空引用类型赋值 null
string? s = null; // Ok
void M(string? s)
{
Console.WriteLine(s.Length); // 产生警告:可能为 null
if (s != null)
{
Console.WriteLine(s.Length); // Ok
}
}
至此,妈妈再也不用担心我的程序到处报 NullReferenceException 啦!
考虑到大部分 Api 以及函数实现都有了对应的 async
版本,而 IEnumerable<T>
和 IEnumerator<T>
还不能方便的使用 async
/await
就显得很麻烦了。
但是,现在引入了异步流,这些问题得到了解决。
我们通过新的 IAsyncEnumerable<T>
和 IAsyncEnumerator<T>
来实现这一点。同时,由于之前 foreach
是基于IEnumerable<T>
和 IEnumerator<T>
实现的,因此引入了新的语法await foreach
来扩展 foreach
的适用性。
例如:
async Task<int> GetBigResultAsync()
{
var result = await GetResultAsync();
if (result > 20) return result;
else return -1;
}
async IAsyncEnumerable<int> GetBigResultsAsync()
{
await foreach (var result in GetResultsAsync())
{
if (result > 20) yield return result;
}
}
C# 8.0 引入了 Index 类型,可用作数组下标,并且使用 ^ 操作符表示倒数。
不过要注意的是,倒数是从 1 开始的。
Index i1 = 3; // 下标为 3
Index i2 = ^4; // 倒数第 4 个元素
int[] a = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{
a[i1]}, {
a[i2]}"); // "3, 6"123123
除此之外,还引入了 “…” 操作符用来表示范围(注意是左闭右开区间)。
var slice = a[i1..i2]; // { 3, 4, 5 }
关于这个下标从 0 开始,倒数从 1 开始,范围左闭右开,笔者刚开始觉得很奇怪,但是发现 Python 等语言早已经做了这样的实践,并且效果不错。因此这次微软也采用了这种方式设计了 C# 8.0 的这个语法。
从此接口中可以包含实现了:
interface ILogger
{
void Log(LogLevel level, string message);
void Log(Exception ex) => Log(LogLevel.Error, ex.ToString()); // 这是一个默认实现重载
}
class ConsoleLogger : ILogger
{
public void Log(LogLevel level, string message) {
... }
// Log(Exception) 会得到执行的默认实现
}
在上面的例子中,Log(Exception)
将会得到执行的默认实现。
现在可以这么写了(patterns 里可以包含 patterns)
IEnumerable<string> GetEnrollees()
{
foreach (var p in People)
{
if (p is Student {
Graduated: false, Name: string name }) yield return name;
}
}
Student { Graduated: false, Name: string name }
检查 p 是否为 Graduated = false
且 Name
为 string
的 Student
,并且迭代返回 name
。
可以这样写之后是不是很爽?
更有:
var area = figure switch
{
Line _ => 0,
Rectangle r => r.Width * r.Height,
Circle c => c.Radius * 2.0 * Math.PI,
_ => throw new UnknownFigureException(figure)
};
典型的模式匹配语句,只不过没有用“match”关键字,而是沿用了
了“switch”关键字。
但是不得不说,一个字,爽!
以前我们写下面这种变量/成员声明的时候,大概最简单的写法就是:
var points = new [] {
new Point(1, 4), new Point(2, 6) };
private List<int> _myList = new List<int>();1212
现在我们可以这么写啦:
Point[] ps = {
new (1, 4), new (3,-2), new (9, 5) };
private List<int> _myList = new ();1212
是不是更加的舒服了?
该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/1037 访问。
一、北京租房市场概况1. 区域特征西城、东城、朝阳、海淀为北京的四个核心区,适合年轻人及年轻人向往的工作机会多集中于这四个区,因此大多数在北京工作的年轻人工作地点都在这四个区内。环绕着这四个核心区依次为石景山、丰台、通州、昌平,这四个区可看作核心区的居住辐射区,许多在核心区工作的人会居住在其相应的配套区。以上八个区统称“城八区”,在某种意义上可以代表北京城的概念。这四个核心区及相应居住...
北京电子科技学院(BESTI)实验报告课程:Java程序与设计 班级:1352姓名:王玥学号:20135232成绩: 指导教师:娄嘉鹏 实验日期:2015.6.9实验密级: 预习程度: 实验时间:15:30-18:00仪器组次: 必修/选修:选修 实验序号:5实验名称:Jav...
集合集合的数学定义:集合是指具有某种特定性质的具体的或抽象的对象汇总而成的集体。其中,构成集合的这些对象则称为该集合的元素,来源百度百科JAVA中集合定义:JAVA中集合是一种集合类,是一种工具,类似于容器,可以存储任意数量的具有共同属性的对象集合的作用:在类的内部对数据进行组织;简单而快速的搜索大量条目;有的集合接口,提供了一些列排列有序的元素,并且可以在序列中间快速的插入或删除有关元素;有的集合接口提供了映射关系,可以通过关键字(key)去快速查找到对应的唯一对象,而这个关键字可以是任意类型。集
代码如下:RadioButton rbtn = new RadioButton(getApplicationContext()); rbtn.setText(String.valueOf(item.get(0))); rbtn.setTextSize(16); rbtn.setTag(Integer.parseInt(String.valueOf(item....
<br />本人搞了一天,总算解决了:<br /> 先说对这个问题的解决方法:设置一个环境变量名为:ANDROID_SDK_HOME,它的值设置为创建模拟器的路径,我的设为“C:/Users/Administrator/.android”,这个路径创建模拟器的路径,至于为何这么设,它默认去这里找吧,不过实际情况,得根据eclipse默认选择的情况,它默认选择在那里呢?可以在eclipse中再新建一个模拟器,可以在新建窗口上面会看到有一个“LIst of existing Android Virtual D
原文链接 : Anthony的简书博客最近在阅读《Linux内核设计与实现》,这里做一下linux中进程相关的知识点整理,以及android中进程的浅析。下面1,2小节整理自《Linux内核设计与实现》 第三章《进程管理》和第四章《进程调度》。第3节整理android中进程的知识点。1 Linux中的进程管理以下内容整理自:《Linux内核设计与实现》 第三章《进程管理》1.1进程和线程进程是资源...
在最近的一份报告中,Canonical 的 Will Cooke 透露,Ubuntu Desktop 团队正在考虑在即将推出的 Ubuntu 17.10 版本中以 GDM(GNOME显示管理器)取代 LightDM 登录管理器。本周早些时候已经有传闻表示 Ubuntu 17.10 将采用 GNOME GDM 显示管理器。特别是现在,在默认情况下,每日构建...
LEADTOOLS中的高级OCR SDK技术是多方面的,可以作为独立功能使用,也可以作为表单识别、支票识别和文档转换等更先进技术的驱动力。程序员自己可以编写三行代码来将图像转换为可搜索文本的文档。LEADTOOLS OCR Module - LEAD Engine(原Advantage Engine )增加了将光学字符识别(OCR)和智能字符识别(ICR)技术合并到应用程序中的一些方法,并且包...
前言在Python开发中,有些情况下,我们可能面临在一台机器上同时安装多版本Python的需求。比如:有多个Python项目,每个项目依赖不同的Python版本。有一个Python项目,它需要同时支持多个Python版本。那么,如何高效地在单台机器上实现多个版本Python(具体来说,这里Python指的是Python解释器)的安装和维护呢?除此之外,我们还可能面临在一台机器上安装多...
使用VTK创建椭球VTK中可以通过vtkParametricEllipsoid类与vtkParametricFunctionSource类协同作用创建一个椭球。介绍一下vtkParametricEllipsoid类。vtkParametricEllipsoid类继承自vtkParametricFunction类,其中我觉得常用的成员函数有:SetXRadius( double )SetYRadius( double )SetZRadius( double )三个函数分别用于设置椭球在X轴、Y轴
Django字段冲突解决项目文件class Topic(BaseModel): """ BBS的话题 """ title = models.CharField(max_length=255, unique=True, help_text='label of topics') content = models.TextField(help_text=u'content of topics') is_online = models.BooleanField(d
问题出发我们知道,在面向对象编程中,每个对象都存在对应的构造函数和析构函数,当对象被创建和销毁时,构造、析构函数会被分别调用。对象从创建到销毁的整个过程,称之为对象的生命周期,为了保证在(1)使用对象时对象是有效的,没有被过早释放;(2)不需要使用对象时,对象被正常销毁而不是一直驻留在内存中,我们需要对象的生命周期进行管理。那么在iOS系统中,对象生命周期管理策略是怎样的呢?为了更好地逐步的了解iOS的内存管理机制,先抛出一些问题:(1)iOS使用引用计数来管理对象的生命周期,什么是引用计数?(2)