C# 7.0 核心技术指南 (7):C#和.NET Framework 简介 1.8&1.8.1

阅读数:6 2019 年 11 月 30 日 23:15

C# 7.0核心技术指南(7):C#和.NET Framework简介 1.8&1.8.1

(C#简史)

内容简介
本书前三章将集中介绍 C#语言。首先介绍基本的语法、类型和变量。而后会介绍一些高级的特性,如不安全代码以及预处理指令。如果你是 C#语言的初学者,请循序渐进地阅读这些章节。
其余各章则涵盖了.NET Framework 的核心功能,包括 LINQ、XML、集合、并发、I/O 和网络、内存管理、反射、动态编程、特性、安全、应用程序域和原生互操作性等主题。第 6 章和第 7 章是后续主题的基础,除这两章之外,其余各章可以按照需要以任何顺序阅读。LINQ 相关的三个章节好按顺序阅读。其中的一些章节需要一些并发相关的知识,这些知识将在第 14 章中介绍。

下文将倒序介绍 C#各个版本的新特性以方便熟悉旧版本语言的读者。


(C# 7.0 新特性)

(C# 7.0 随 Visual Studio 2017 发布。)

1.8.1.1 数字字面量的改进

C# 7 中,数字字面量可以使用下划线来改善可读性、它们称为数字分隔符而被编译器忽略:

复制代码
int million = 1_000_000;

二进制字面量可以使用 0b 前缀进行标识:

复制代码
var b = 0b1010_1011_1100_1101_1110_1111;

1.8.1.2 输出变量及参数忽略

C# 7 中,调用含有 out 参数的方法将更加容易。首先,可以非常自然地声明输出变量:

复制代码
bool successful = int.TryParse ("123", out int result);
Console.WriteLine (result);

当调用含有多个 out 参数的方法时,可以使用下划线字符忽略你并不关心的参数:

复制代码
SomeBigMethod (out _, out _, out _, out int x, out _, out _, out _);
Console.WriteLine (x);

1.8.1.3 模式

is 运算符也可以自然地引入变量了,称为模式变量(请参见 3.2.2.5 节):

复制代码
void Foo (object x)
{
if (x is string s)
Console.WriteLine (s.Length);
}

switch 语句同样支持模式,因此我们不仅可以选择常量还可以选择类型(请参见 2.11.3.5 节);可以使用 when 子句来指定一个判断条件;或是直接选择 null:

复制代码
switch (x)
{
case int i:
Console.WriteLine ("It's an int!");
break;
case string s:
Console.WriteLine (s.Length); // We can use the s variable
break;
case bool b when b == true: // Matches only when b is true
Console.WriteLine ("True");
break;
case null:
Console.WriteLine ("Nothing");
break;
}

1.8.1.4 局部方法

局部方法是声明在其他函数内部的方法(请参见 3.1.2.4 节):

复制代码
void WriteCubes()
{
Console.WriteLine (Cube (3));
Console.WriteLine (Cube (4));
Console.WriteLine (Cube (5));
int Cube (int value) => value * value * value;
}

局部方法仅仅在其包含函数内可见,它们可以像 Lambda 表达式那样捕获局部变量。

1.8.1.5 更多的表达式体成员

C# 6 引入了以“胖箭头”语法表示的表达式体的方法、只读属性、运算符以及索引器。而 C# 7 更将其扩展到了构造函数、读 / 写属性和终结器中:

复制代码
public class Person
{
string name;
public Person (string name) => Name = name;
public string Name
{
get => name;
set => name = value ?? "";
}
~Person () => Console.WriteLine ("finalize");
}

1.8.1.6 解构器

C# 7 引入了解构器模式。构造器一般接受一系列值(作为参数)并将其赋值给字段,而解构器则正相反,它将字段反向赋值给变量。以下示例为 Person 类书写了一个解构器(不包含异常处理):

复制代码
public void Deconstruct (out string firstName, out string lastName)
{
int spacePos = name.IndexOf (' ');
firstName = name.Substring (0, spacePos);
lastName = name.Substring (spacePos + 1);
}

解构器以特定的语法进行调用:

复制代码
var joe = new Person ("Joe Bloggs");
var (first, last) = joe; // Deconstruction
Console.WriteLine (first); // Joe
Console.WriteLine (last); // Bloggs

1.8.1.7 元组

也许对于 C# 7 来说最值得一提的改进当属显式的元组(tuple)支持(请参见 4.10 节)。元组提供了一种存储一系列相关值的简单方式:

复制代码
var bob = ("Bob", 23);
Console.WriteLine (bob.Item1); // Bob
Console.WriteLine (bob.Item2); // 23

C#的新元组实质上是使用 System.ValueTuple<…> 泛型结构的语法糖。多亏了编译器的“魔力”,我们还可以对元组的元素进行命名:

复制代码
var tuple = (Name:"Bob", Age:23);
Console.WriteLine (tuple.Name); // Bob
Console.WriteLine (tuple.Age); // 23

有了元组,函数再也不必通过一系列 out 参数来返回多个值了:

复制代码
static (int row, int column) GetFilePosition() => (3, 10);
static void Main()
{
var pos = GetFilePosition();
Console.WriteLine (pos.row); // 3
Console.WriteLine (pos.column); // 10
}

元组隐式地支持解构模式,因此很容易解构为若干独立的变量。因此,上述 Main 方法中的 GetFilePosition 返回的元组将存储于两个局部变量 row 和 column 中:

复制代码
static void Main()
{
(int row, int column) = GetFilePosition(); // Creates 2 local variables
Console.WriteLine (row); // 3
Console.WriteLine (column); // 10
}

1.8.1.8 throw 表达式

在 C# 7 之前,throw 一直是一个语句。现在,它也可以作为表达式出现在表达式体函数中:

复制代码
public string Foo() => throw new NotImplementedException();

throw 表达式也可以出现在三无判断运算符中:

复制代码
string Capitalize (string value) =>
value == null ? throw new ArgumentException ("value") :
value == "" ? "" :
char.ToUpper (value[0]) + value.Substring (1);

1.8.1.9 其他改进

C#还包含一系列针对特定的场景进行专门的微小优化的功能(请参见 2.8.5 节和 2.8.6 节)。同时,我们可以在异步方法声明中包含返回类型而非 Task/Task

C# 7.0核心技术指南(7):C#和.NET Framework简介 1.8&1.8.1

购书地址 https://item.jd.com/12681788.html?dist=jd

评论

发布