[翻譯]歡迎來到 C# 7.1
在 C# 中,我們一直傾向於主要版本:捆綁了很多功能,並且不太頻繁地發布。當我們談到 C#6.0時,我們甚至還經常忽略掉后面的“.0”!
在 C#7.0 這一“波”中,我們正在嘗試新的東西。像 Visual Studio 這樣頻繁的升級節奏,為什么 C# 不能也頻繁的升級呢,這已經不存在技術原因了。所以這一次,我們正在擁抱“點發布”的概念; C#的次要版本會以更短的間隔更新,並且提供有用且較小的語言功能。這意味着您不必等待很長時間才能獲得高級特性,而且還可以更容易地將C#版本與相關功能的發布相一致,例如.NET。
當然,對於團隊來說,將語言升級到新版本“一直以來”都是件麻煩事,對於個人來說還好。 Visual Studio 2017 允許您決定是否切換到最新版本,或使用主要的版本。你可以選擇你的喜好。
第一個“點發布”
在2017年8月,我們發布了 C# 的第一個“點發布”版。它被稱為 C#7.1,其主要目的是為我們的“點發布”積累經驗,並且保證沒有太多的依賴以使問題復雜化。
因此,C#7.1是一個很小的版本,只有少數(但精心挑選的)新語言特性; 我們認為它們是有用的,並且一定在某些場景下有用。 Visual Studio 2017 Update 15.3 開始支持。
現在我們來看一下!這是一個涵蓋了三個 C#7.1 新特性的程序,加上最近 C#7.0 的一些特性,旨在使其有趣。
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using static System.Console;
class Program
{
static async Task Main(string[] args)
{
var results = Enumerable.Range(1, 40)
.Select(input => (input, task: FibonacciAsync(input)))
.ToArray();
foreach (var tuple in results)
{
WriteLine($"Fib {tuple.input} = {await tuple.task}");
}
}
private static Task<int> FibonacciAsync(int n, CancellationToken token = default)
{
return Task.Run(() => Fib(n).curr, token);
(int curr, int prev) Fib(int i)
{
if (i is 0) return (1, 0);
var (c, p) = Fib(i - 1);
return (c + p, c);
}
}
}
它在線程池中並行計算前40個斐波納契數,並按順序打印出來。
我們來看看這里使用的每個新的 C#7.1 特性。要全面的了解 C#7.1 中新特性,請查看文檔。
Main 方法可以 Async
現在 Main 入口點方法可以返回 Task 或 Task
當然,常用的方法就是使 Main 方法異步,你可以這樣做:
static async Task Main(string[] args)
這會讓你可以直接在 Main 方法里 await, 這在以前是不行的。
WriteLine($"Fib {tuple.input} = {await tuple.task}");
以前的話,想達到這個效果是很麻煩:首先創建一個 async 的輔助方法,MainAsync,寫上所有邏輯,然后寫個怪異的 Main 方法:
static void Main(string[] args) => MainAsync().GetAwaiter().GetResult();
現在你可以直接讓你的 Main 方法 async,編譯器會幫你重寫它。
推斷元組元素的名稱
在這個lambda表達式里面的查詢:
input => (input, task: FibonacciAsync(input))
您注意到,我們創建一個元組,但只為第二個元素提供一個名稱, task。然后我們可以直接這么寫
WriteLine($"Fib {tuple.input} = {await tuple.task}");
用名稱tuple.input來訪問第一個元素。這是因為當您創建一個有名稱的表達式元組時,如上面的lambda表達式中的輸入,我們將自動給予相應的元組元素一個名稱。
Default literals 默認常值
如果默認表達式有預期類型,那么現在可以省略對類型的說明,就像在 FibonacciAsync 方法的簽名中的 CancellationToken 一樣:
private static Task<int> FibonacciAsync(int n, CancellationToken token = default)
這避免了繁瑣的類型名稱重復,或者當已經由上下文給出時,輸出長的類型名稱。
What’s next?
我們已經在開發 C#7.2,以及下一個主要版本的特性。 如果你好奇,你可以跟隨並參加C#語言設計GitHub repo:github.com/dotnet/csharplang