接上回c# 8.0特性介紹, 這回我們開始介紹最新的C# 新特性,需要了解7.0特性以及上一篇文章的請點擊下面的鏈接
當然放上目錄:
- Readonly 成員
- 默認接口方法
- 模式匹配增強功能
- Using申明
- 靜態本地函數
- 可處置的ref結構
- 可為空的引用類型
- 異步流
- 索引和範圍
- Null合併賦值
- 非託管構造類型
- 嵌套表達式中的Stackalloc
- 內插逐字字符串的增強功能
- 平臺支持情況
靜態本地函數
在上次介紹c# 7.0增強特性中提到可以添加本地函數來增強代碼的模塊化以及可讀性,這次再來看看在c# 8.0中上次提到的本地函數可以進一步被申明為靜態的,即在本地函數前面加上 static 關鍵字,由於加上static後,本地函數變成靜態的,所以可以確保本地函數不引用或使用封閉範圍內的任何變量。示例:
<code>int Demo()
{
int y = 5;
int x = 7;
return Add(x, y);
static int Add(Int32 left, Int32 right) => left + right;
}/<code>
Disposable ref structs
ref struct 這樣聲明的結構無法實現額外的接口,因此無法實現IDisposable這個接口,但是可以通過提供一個可以訪問的void Dispose()方法,來實現Dispose的功能; readonly ref struct 這樣的結構也是可以的
可為空引用類型
在可為空註釋上下文中,引用類型的任何變量都被視為不可為空引用類型 。 若要指示一個變量可能為 null,必須在類型名稱後面附加 ?,以將該變量聲明為可為空引用類型 。
任何引用類型都可以具有四個“為 Null 性”中的一個,它描述了何時生成警告 :
- 不可為空:無法將 null 分配給此類型的變量。 在取消引用之前,無需對此類型的變量進行 null 檢查。
- 可為空:可將 null 分配給此類型的變量。 在不首先檢查 null 的情況下取消引用此類型的變量時發出警告。
- 無視:這是 C# 8.0 之前版本的狀態。 可以取消引用或分配此類型的變量而不發出警告。
- 未知:這通常針對類型參數,約束不告知編譯器類型是否必須是“可為空”或“不可為空” 。
在C#8.0 以前的版本。默認被認為是不啟用的,在之後的版本中用 .csproj 文件中的 Nullable 元素為項目設置可為空註釋上下文和可為空警告上下文
<code>// .csproj 文件中的配置是全局的
<nullable>enable/<nullable>
<nullable>warnings/<nullable>
<nullable>annotations/<nullable>
<nullable>disable/<nullable>
// 使用指令來局部指定 示例如下
#nullable enable 將可為空註釋上下文和可為空警告上下文設置為“已啟用” 。
#nullable disable warnings 將可為空警告上下文設置為“已禁用” 。/<code>
異步流
從 C# 8.0 開始,可以創建並以異步方式使用流。 返回異步流的方法有三個屬性:
- 它是用 async 修飾符聲明的。
- 它將返回 IAsyncEnumerable
。 - 該方法包含用於在異步流中返回連續元素的 yield return 語句。
使用異步流需要在枚舉流元素時在 foreach 關鍵字前面添加 await 關鍵字。
<code>await foreach (var number in GenerateSequence())
{
Console.WriteLine(number);
}/<code>
索引和範圍
索引和範圍為訪問序列中的單個元素或範圍提供了簡潔的語法。此特性依賴於兩個新類型以及兩個新運算符
<code>// A string array contains some string
var words = new string[]
{
// index from start index from end
"The", // 0 ^9
"quick", // 1 ^8
"brown", // 2 ^7
"fox", // 3 ^6
"jumped", // 4 ^5
"over", // 5 ^4
"the", // 6 ^3
"lazy", // 7 ^2
"dog" // 8 ^1
}; // 9 (or words.Length) ^0
Console.WriteLine($"The last word is {words[^1]}"); // writes "dog"
var quickBrownFox = words[1..4]; // 包含 quick brown fox 不包含 jumped
var lazyDog = words[^2..^0]; // 包含 lazy dog
var allWords = words[..]; // 包含 "The" 到 "dog"的所有元素
var firstPhrase = words[..4]; // 包含 "The" 到 "fox"
var lastPhrase = words[6..]; // 包含 "the", "lazy", "dog"
Range phrase = 1..4; // 通過此來聲明一個範圍
var text = words[phrase]; // 在中括號中使用剛剛聲明的phrase/<code>
Null 合併賦值
新的運算符被 ??= 定義,僅當左操作數計算為 null 時,才能使用運算符 ??= 將其右操作數的值分配給左操作數。
<code>Listnumbers = null; /<code>
int? i = null;
numbers ??= new List();
numbers.Add(i ??= 17);
非託管構造類型
在 C# 7.3 及更低版本中,構造類型(包含至少一個類型參數的類型)不能為非託管類型。 從 C# 8.0 開始,如果構造的值類型僅包含非託管類型的字段,則該類型不受管理。
<code>public struct Coords/<code>
{
public T X;
public T Y;
}
// Coords類型為 C# 8.0 及更高版本中
// 的非託管類型。 與任何非託管類型一樣,可
// 以創建指向此類型的變量的指針,或針對此類
// 型的實例在堆棧上分配內存塊:
Span<coords>> coordinates = stackalloc[]
{
new Coords{ X = 0, Y = 0 }, /<coords>
new Coords{ X = 0, Y = 3 },
new Coords{ X = 4, Y = 0 }
};
嵌套表達式中的 stackalloc
如果 stackalloc 表達式的結果為 System.Span
<code>Spannumbers = stackalloc[] { 1, 2, 3, 4, 5, 6 }; /<code>
var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6 ,8 });
Console.WriteLine(ind); // output: 1
內插逐字字符串的增強功能
內插逐字字符串中 $ 和 @ 標記的順序可以任意安排:$@"..." 和 @$"..." 均為有效的內插逐字字符串。 在早期 C# 版本中,$ 標記必須出現在 @ 標記之前。
<code>// in previous versions of c#
var filePath = $@"c:\\demoDir\\{testDir}\\demo.txt";
// in c# 8.0 but also type as bellow
var filePath = @$"c:\\demoDir\\{testDir}\\demo.txt";/<code>
好了,本次的主要內容就到這裡了後面的內容是關於各個.Net平臺的支持情況
目標框架 version C# 語言版本的默認值
.NET Core 3.x C# 8.0
.NET Core 2.x C# 7.3
.NET Standard 2.1 C# 8.0
.NET Standard 2.0 C# 7.3
.NET Standard 1.x C# 7.3
.NET Framework all C# 7.3
閱讀更多 技術鵬 的文章
關鍵字: 編譯器