C# 8 - Nullable Reference Types 可空引用類型html
從C# 8 開始,本地方法就能夠是靜態的了。 htm
與其餘的本地方法不一樣,靜態的本地方法沒法捕獲任何本地狀態量。 blog
直接看例子:
這段代碼裏有兩個本地方法,他們分別對實例的一個字段和方法裏的一個本地變量進行了修改操做,也就是捕獲並更新了本地的狀態。
其運行結果是:
能夠看到類的成員字段和方法本地變量的狀態都被這兩個本地方法修改了。。
可是不少狀況下,你並不但願類的實例字段和方法本地變量的值被捕獲或修改。在C# 8裏面,你可使用靜態本地方法來達到這個目的。
其作法很簡單,就是在原來這兩個本地方法前面加上static關鍵字便可:
能夠看到程序報錯了,這是由於靜態本地方法是不能夠訪問和捕獲實例的狀態的,包括實例成員和方法本地變量。
針對第一個本地方法,我直接把更新本地變量的語句去掉:
而針對第二個本地方法,若是你真的想修改實例成員的狀態,那麼就須要把成員改成靜態的:
其運行結果是:
C# 8的這個特性對可讀性其實沒有特別大的幫助,可是它卻能夠防止本地方法捕獲實例狀態,在一些狀況下,這對性能有很大的幫助。
C# 7.2 裏面出現了ref struct,可是它的缺點就是不能夠實現接口。
看這個例子:
這個struct裏面包含了一個不安全(unsafe)資源,當我用完以後,這個資源是須要被清理掉的。
在C# 8以前,咱們沒法針對這個struct使用using語句,由於這個struct沒法實現IDisposable接口。
可是從C# 8開始,ref struct無需實現IDisposable接口也可使用using語句或者using聲明,只要它提供了適當的方法便可。以下圖:
而後咱們就可使用using語句了:
或者using聲明:
從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>仍然是託管的。
看例子。
在C# 8以前,咱們能夠經過以下代碼來保證numbers被初始化:
可是從C# 8開始,咱們能夠更簡單的表達咱們的意思:
這個特性帶來的好處是,在變量名不是特別短小精悍的狀況下,會少打不少字符。
C# 8裏,針對內插逐字字符串的功能作了一點點加強。
在C# 8以前,這樣寫是沒毛病的:
可是這樣寫就不行:
可是從C# 8開始,兩種寫法都是正確的:
都不會報錯了。