其它關于C# 8和.NET Core 3.0新特性的文章:
C# 8 - Nullable Reference Types 可空參考型別
C# 8 - 模式匹配
C# 8 - Range 和 Index(范圍和索引)
C# 8.0 - 默認介面方法
C# 8 - using宣告 和 異步流
.NET Core 3.0 里新的JSON API
.NET Core 3.0 本地工具
.NET Core 3.0 構建和部署
靜態本地方法
從C# 8 開始,本地方法就可以是靜態的了,
與其他的本地方法不同,靜態的本地方法無法捕獲任何本地狀態量,
直接看例子:
這段代碼里有兩個本地方法,他們分別對實體的一個欄位和方法里的一個本地變數進行了修改操作,也就是捕獲并更新了本地的狀態,
其運行結果是:
可以看到類的成員欄位和方法本地變數的狀態都被這兩個本地方法修改了,,
但是很多情況下,你并不希望類的實體欄位和方法本地變數的值被捕獲或修改,在C# 8里面,你可以使用靜態本地方法來達到這個目的,
其做法很簡單,就是在原來這兩個本地方法前面加上static關鍵字即可:
可以看到程式報錯了,這是因為靜態本地方法是不可以訪問和捕獲實體的狀態的,包括實體成員和方法本地變數,
針對第一個本地方法,我直接把更新本地變數的陳述句去掉:
而針對第二個本地方法,如果你真的想修改實體成員的狀態,那么就需要把成員改為靜態的:
其運行結果是:
優點
C# 8的這個特性對可讀性其實沒有特別大的幫助,但是它卻可以防止本地方法捕獲實體狀態,在一些情況下,這對性能有很大的幫助,
Disposable ref Structs
C# 7.2 里面出現了ref struct,但是它的缺點就是不可以實作介面,
看這個例子:
這個struct里面包含了一個不安全(unsafe)資源,當我用完之后,這個資源是需要被清理掉的,
在C# 8之前,我們無法針對這個struct使用using陳述句,因為這個struct無法實作IDisposable介面,
但是從C# 8開始,ref struct無需實作IDisposable介面也可以使用using陳述句或者using宣告,只要它提供了適當的方法即可,如下圖:
然后我們就可以使用using陳述句了:
或者using宣告:
只讀struct成員
從C# 8開始,我們可以在struct的成員上使用readonly修飾符,
為struct的成員添加readonly修飾符就表示告訴編譯器和開發者該成員不可以修改struct的狀態,
看下面這個例子:
這里的ToString()方法不會修改Point這個struct的狀態,所以我們可以在該方法上添加readonly修飾符來表示其只讀:
但是這里會出現警告,因為 ToString 訪問了未標記為 readonly 的 Distance 屬性,也就是需要創建防御性副本時,編譯器會發出警告,
由于Distance屬性不會修改狀態,所以可以在它前邊加上readonly修飾符以修復此警告:
請注意,readonly 修飾符對于只讀屬性是必須要添加的, 編譯器會假設 get 訪問器可以修改狀態;所以必須顯式宣告 readonly,
但是自動實作的屬性則是一個例外;編譯器將所有自動實作的 Getter 視為 readonly,因此,此處無需向 X 和 Y 屬性添加 readonly 修飾符,
如果我在該struct里面再添加一個修改狀態的方法:
由于該方法確實修改了struct的狀態,所以如果在該方法上再加上readonly修飾符的話,編譯器就會報錯,
而如果我把readonly修飾符去掉的話,那么就不會報錯了:
在C#里面,型別可以分為托管型別和非托管型別,在之前的.NET版本中,只有內置的值型別、列舉型別和僅包含非托管型別成員的struct等這些型別才可以是非托管型別,其中內置的值型別有:
-
byte
-
int
-
char
-
float
-
bool
-
…
而構造型別(指包含至少一個型別引數的型別)不能為非托管型別,
看下面這個泛型struct:
在C# 7里,無論這里的T是int還是object,該型別都不可以是非托管型別,即使T是一個非托管型別,
而在C# 8里,如果構造型別的所有型別引數都是非托管型別的,那么這個構造型別就是非托管的,
所以Coords<int> 型別在 C# 8.0 及更高版本中是非托管型別,但是Coords<object>仍然是托管的,
Null 合并賦值
看例子,
在C# 8之前,我們可以通過如下代碼來保證numbers被初始化:
但是從C# 8開始,我們可以更簡單的表達我們的意思:
這個特性帶來的好處是,在變數名不是特別短小精悍的情況下,會少打很多字符,
內插逐字字串的增強功能
C# 8里,針對內插逐字字串的功能做了一點點增強,
在C# 8之前,這樣寫是沒毛病的:
但是這樣寫就不行:
但是從C# 8開始,兩種寫法都是正確的:
都不會報錯了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/110584.html
標籤:C#
下一篇:C# 獲取所有可用的列印機
