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的其餘特性


分享到:


相關文章: