C#8.0特性(一)

接上回c# 7.0特性介绍, 这回我们开始介绍最新的C# 新特性,需要了解7.0特性的请点击下面的链接

话说,这都0202年了,当然得用上最香的8.0了,本文的主要内容:

  • Readonly 成员
  • 默认接口方法
  • 模式匹配增强功能
  • Using声明
  • 静态本地函数
  • 可处置的ref结构
  • 可为空的引用类型
  • 异步流
  • 索引和范围
  • Null合并赋值
  • 非托管构造类型
  • 嵌套表达式中的Stackalloc
  • 内插逐字字符串的增强功能
  • 平台支持情况

本文考虑到篇幅问题将分为两部分介绍

c# 8.0 新功能及各种增强的功能

Readonly 成员

在新版本的c# 中,可以将readonly用于结构体,可以提供更加精细的类型构造意图,另外,使用Readonly的成员匀访问未被声明为Readonly的属性时,编译器会生成警告:如下:

<code>public struct Point
{
public double X { get; set; }
public double Y { get; set; }
public double Distance => Math.Sqrt(X * X + Y * Y);

public readonly override string ToString() =>
$"({X}, {Y}) is {Distance} from the origin";
// warning CS8656: Call to non-readonly member 'Point.Distance.get'
// from a 'readonly' member results in an implicit copy of 'this'
}/<code>

可以通过将Distance标记为Readonly来消除这个Warn

由于编译器将所有自动实现的 Getter 视为 readonly,因此,此处无需向 X 和 Y 属性添加 readonly 修饰符

在下面的例子中,代码不会执行,除非删除readonly标记,通过这些语法能够指定设计目的,使编译器能基于此优化

<code>public readonly void Translate(int xOffset, int yOffset)
{
X += xOffset;
Y += yOffset;
}/<code>

默认接口方法

在新版本的c# 语法中可以为接口中的方法提供默认实现,这个功能不会影响已有的实现的功能的兼容性。这个功能可以让接口的实现方在没有确定实现方案时先接受接口提供的默认方案,在确定方案后又可以无缝的升级功能

模式匹配增强功能

switch表达式演示

<code>public enum Rainbow
{
Red,
Orange,
Yellow
}
public static RGBColor FromRainbow(Rainbow colorBand) =>
colorBand switch
{
Rainbow.Red => new RGBColor(0xFF, 0x00, 0x00),
Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand))
};/<code>

上述语法几个改进之处

  1. 变量位于 switch 之前,与switch语句进行区分。
  2. 将 case 和 : 元素替换为 =>。 它更简洁,更直观。
  3. 将 default 替换为 _ 弃元。
  4. 正文是表达式,不是语句。

可以与之前的switch 语句进行对比

<code>public static RGBColor FromRainbowClassic(Rainbow colorBand)
{
switch (colorBand)
{
case Rainbow.Red:
return new RGBColor(0xFF, 0x00, 0x00);

case Rainbow.Orange:
return new RGBColor(0xFF, 0x7F, 0x00);
case Rainbow.Yellow:
return new RGBColor(0xFF, 0xFF, 0x00)
default:
throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand));
};
}/<code>

此外增强的模式匹配还有属性模式以,元组模式以及位置模式 代码示例:

<code>// 属性匹配模式
// 其中Address类包含State属性
public static decimal ComputeSalesTax(Address location, decimal salePrice) =>
location switch
{
{ State: "WA" } => salePrice * 0.06M,
{ State: "MN" } => salePrice * 0.75M,
{ State: "MI" } => salePrice * 0.05M,
// other cases removed for brevity...
_ => 0M
};
// 元组模式
public static string RockPaperScissors(string first, string second)
=> (first, second) switch
{
("rock", "paper") => "rock is covered by paper. Paper wins.",
("rock", "scissors") => "rock breaks scissors. Rock wins.",
("paper", "rock") => "paper covers rock. Paper wins."
(_, _) => "tie"
};
// 位置模式
public enum Quadrant
{
Unknown,
Origin,
One,
Two,
Three,
Four,
OnBorder
}
static Quadrant GetQuadrant(Point point) => point switch
{
(0, 0) => Quadrant.Origin,

var (x, y) when x > 0 && y > 0 => Quadrant.One,
var (x, y) when x < 0 && y > 0 => Quadrant.Two,
var (x, y) when x < 0 && y < 0 => Quadrant.Three,
var (x, y) when x > 0 && y < 0 => Quadrant.Four,
var (_, _) => Quadrant.OnBorder,
_ => Quadrant.Unknown
};
// Switch 表达式要么生成值,要么引发异常。 如果这些情况都不匹配,
// 则 switch 表达式将引发异常。 如果没有在 switch 表达式中涵盖所有
// 可能的情况,编译器将生成一个警告。/<code>

在新版本的C# 中可以以如下代码使用using语句

<code>using var file = new System.IO.StreamWriter("TestFile.txt");  // c# 8.0+
using (var file = new System.IO.StreamWriter("TestFile.txt")) // c# 8.0 之前
{
// Do something
}/<code>

新的语法更加灵活,不必要因为using语句导致一些变量作用域受到影响,而把声明和赋值分离,同时在语句所在代码作用域结束的时候调用using声明的变量的Dispose方法

由于篇幅原因,在下一篇接着介绍C#8.0的其余特性


分享到:


相關文章: