VS 2019 要来了,是时候了解一下 C# 8.0 新功能
近日,微軟發布了 Visual Studio 2019 的發布日期,2019 年 4 月 2 日 Visual Studio 2019?將正式和大家見面,同時微軟還將提供發布現場實時直播。
除了 Visual Studio 2019 自身之外,VS 2019 的發布還牽動著很多 C# 開發者的心。雖然一個月之前發布的 Visual Studio 2019 Preview 版本已經可以試用 C# 的某些新功能,但還有一些是不可試用的。
下面我們就來看一下微軟官方對 C#8.0 重要功能的概述。
可空的引用類型
此功能的目的是防止無處不在的空引用異常,空引用異常已經困擾面向對象編程半個世紀了。該功能將阻止開放者將 null 值放入到普通的引用類型中,例如 String 類型不可為空。但它不是強制性的 error,而是比較溫和的 warning。
這些異常現在已經過了半個世紀的面向對象編程。
它阻止你 null 進入普通的引用類型,例如 string- 它使這些類型不可為空!它是溫和的,有警告,而不是錯誤。但是在現有代碼上會出現新警告,因此您必須選擇使用該功能(您可以在項目,文件甚至源代碼級別執行此功能)。
string s = null; // Warning: Assignment of null to non-nullable reference type
如果你想要使用 null 怎么辦?可以使用可為空的引用類型,例如 string?:
string? s = null; // Ok
當你使用了可空引用時,需要先檢查一下其是否為 null,編譯器會分析代碼流,以查看 null 值是否可以將其用于您使用它的位置:
void M(string? s)
{
Console.WriteLine(s.Length); // Warning: Possible null reference exception
if (s != null)
{
Console.WriteLine(s.Length); // Ok: You won't get here if s is null
}
}
C# 允許表達可空的意圖,但是在不遵守規則時會發出警告。
異步流
C#5.0 的 async / await 功能允許在簡單的代碼中使用(并生成)異步結果,而無需回調:
async Task<int> GetBigResultAsync()
{
var result = await GetResultAsync();
if (result > 20) return result;
else return -1;
}
下面我們來介紹一下大家期待已久的 IAsyncEnumerable,?異步版本的 IEnumerable。該語言允許 await foreach 使用元素,并使用 yield return 生成元素。
async IAsyncEnumerable<int> GetBigResultsAsync()
{
await foreach (var result in GetResultsAsync())
{
if (result > 20) yield return result;
}
}
范圍和索引
我們正在添加一個可用于索引的 Index 類型。你可以使用 int 從頭創建,也可以使用 ^ 從末尾開始計算前綴運算符:
Index i1 = 3; // number 3 from beginning
Index i2 = ^4; // number 4 from end
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // “3, 6”
另外,我們還引入了一個 Range 類型,它由兩個 Indexes?組成,一個用于開始,一個用于結束,并且可以用 x…y?范圍表達式編寫。
可以使用 a 進行索引 Range 以生成切片:
var slice = a[i1…i2]; // { 3, 4, 5 }
接口成員的默認實現
今天,大家對于界面都有這樣一個需求:在不破壞現有狀態的情況下添加一個成員。
在 C#8.0 中,我們會為接口成員提供一個主體。如果有人沒有實現該成員(或者是在編寫代碼時還沒有實現),會獲得默認實現。
interface ILogger
{
void Log(LogLevel level, string message);
void Log(Exception ex) => Log(LogLevel.Error, ex.ToString()); // New overload
}
class ConsoleLogger : ILogger
{
public void Log(LogLevel level, string message) { ... }
// Log(Exception) gets default implementation
}
在 ConsoleLogger 類不需要實現 ILogger 的 Log(Exception) 重載,因為它已經默認實現了。現在只要給當前實現者提供了默認實現,就可以向現有公共接口添加新成員。
遞歸模式
我們允許 pattern 中包含其他 pattern:
IEnumerable<string> GetEnrollees()
{
foreach (var p in People)
{
if (p is Student { Graduated: false, Name: string name }) yield return name;
}
}
pattern Student { Graduated: false, Name: string name }主要檢查 Person 是 a?Student,然后將常量 pattern false 應用于其 Graduated 屬性以查看它們是否仍然已注冊,并將 pattern string name 應用于其 Name 屬性以獲取其名稱(如果為非 null)。因此,如果 p 是一個 Student,尚未畢業并且姓名非空,那么我們就可以 yield return 這個名字。
Switch 表達式
帶有 pattern 的 switch 語句在 C#7.0 中已經非常強大了,但是編寫起來卻很麻煩,而 Switch 表達式卻是一個解決這種問題的、“輕量級”的版本。
var area = figure switch
{
Line _ ? ? ?=> 0,
Rectangle r => r.Width * r.Height,
Circle c ? ?=> Math.PI * c.Radius * c.Radius,
_ ? ? ? ? ? => throw new UnknownFigureException(figure)
};
目標類型的新表達式
在許多情況下,往往創建新對象時,類型已經從上下文中給出。在這些情況下,我們會讓你省略類型:
Point[] ps = { new (1, 4), new (3,-2), new (9, 5) }; // all Points
C# 大版本關鍵更新回顧
C#1.0(Visual Studio .NET)
Classes
Structs
Interfaces
Events
Properties
Delegates
Expressions
Statements
Attributes
Literal
C#2(VS 2005)
Generics
Partial types
Anonymous methods
Iterators
Nullable types
Getter/setter separate accessibility
Method group conversions (delegates)
Static classes
Delegate inferenc
C#3(VS 2008)
Implicitly typed local variables
Object and collection initializers
Auto-Implemented properties
Anonymous types
Extension methods
Query expressions
Lambda expression
Expression trees
Partial methods
C#4(VS 2010)
Dynamic binding
Named and optional arguments
Co- and Contra-variance for generic delegates and interfaces
Embedded interop types (“NoPIA”
C#5(VS 2012)
Asynchronous methods
Caller info attributes
C#6(VS 2015)
Draft Specification online
Compiler-as-a-service (Roslyn)
Import of static type members into namespace
Exception filters
Await in catch/finally blocks
Auto property initializers
Default values for getter-only properties
Expression-bodied members
Null propagator (null-conditional operator, succinct null checking)
String interpolation
nameof operator
Dictionary initializer
C#7.0(Visual Studio 2017)
Out variables
Pattern matching
Tuples
Deconstruction
Discards
Local Functions
Binary Literals
Digit Separators
Ref returns and locals
Generalized async return types
More expression-bodied members
Throw expressions
平臺依賴
大多數的 C# 8.0 功能都可以在任何版本的.NET 上運行,但也有一些功能是有平臺依賴性的,例如異步流、范圍和索引都依賴 .NET Standard 2.1 一部分的新框架類型。其中,.NET Standard 2.1、.NET Core 3.0 以及 Xamarin,Unity 和 Mono 都將實現 .NET Standard 2.1,而.NET?Framework 4.8 不會,所以如果你使用的是 .NET Framework 4.8,那么 C# 8.0 的部分功能可能不能使用。
另外,接口成員的默認實現也依賴新的運行時增強功能,所以此功能也不適用于 .NET Framework 4.8 和舊版本的 .NET。
原文地址:https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的VS 2019 要来了,是时候了解一下 C# 8.0 新功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【招聘(北京)】北森测评招聘 .NET
- 下一篇: 重新解读DDD领域驱动设计(一)