日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

[翻译]初试C# 8.0

發(fā)布時間:2023/12/4 C# 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [翻译]初试C# 8.0 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文地址:?https://blogs.msdn.microsoft.com/dotnet/2018/12/05/take-c-8-0-for-a-spin/

初試C# 8.0

昨天我們宣布了Visual Studio 2019的第一個預(yù)覽版(使用Visual Studio 2019提高每個開發(fā)人員的工作效率)和.NET Core 3.0(宣布.NET Core 3預(yù)覽1和開源Windows桌面框架)。

其中一個令人興奮的方面是你可以使用C#8.0中的一些功能!在這里,我將帶您進(jìn)行一次導(dǎo)游,了解您可以在預(yù)覽中嘗試的三種新的C#功能。并非所有C#8.0功能都可用。如果您想了解所有主要功能,請閱讀最近發(fā)布Building C# 8.0,或查看Channel 9或YouTube。

做好準(zhǔn)備

首先,下載并安裝.NET Core 3.0的預(yù)覽版1和Visual Studio的2019的預(yù)覽版1。在Visual Studio中,確保選擇工作負(fù)載“.NET Core跨平臺開發(fā)”(如果您忘記了,可以稍后通過打開Visual Studio安裝程序并單擊Visual Studio 2019預(yù)覽頻道上的“修改”來添加它)。

啟動Visual Studio 2019預(yù)覽版,創(chuàng)建新項(xiàng)目,然后選擇“Console App(.NET Core)”作為項(xiàng)目類型。

項(xiàng)目啟動并運(yùn)行后,將其目標(biāo)框架更改為.NET Core 3.0(在解決方案資源管理器中右鍵單擊該項(xiàng)目,選擇“屬性”并使用“應(yīng)用程序”選項(xiàng)卡上的下拉菜單)。然后選擇C#8.0作為語言版本(在項(xiàng)目頁面的Build選項(xiàng)卡上單擊“Advanced ...”并選擇“C#8.0(beta)”)。

現(xiàn)在,您可以輕松獲得所有語言功能和支持框架類型!

可空的引用類型

可空引用類型功能旨在警告您代碼中的null不安全行為。既然我們之前沒有這樣做過,那么現(xiàn)在就開始改變吧!為避免這種情況,您需要選擇加入該功能。

不過,在我們開啟它之前,讓我們寫一些非常糟糕的代碼:

如果你運(yùn)行它,你當(dāng)然會得到一個空引用異常。你陷入了黑洞!你怎么知道不要在特定的地方間接引用s?嗯,因?yàn)樵谇耙恍蟹峙淞薾ull。但是在現(xiàn)實(shí)生活中,它可能不是在前一行,而是在你編寫代碼的三年后在地球另一端運(yùn)行的其他人程序集中。你怎么知道不寫那個?這是可空引用類型要回答的問題!所以讓我們打開它們吧!

對于一個新項(xiàng)目,你應(yīng)該立即打開它們。事實(shí)上,我認(rèn)為它們應(yīng)該在新項(xiàng)目中默認(rèn)啟用,但我們在預(yù)覽中沒有這樣做。打開它們的方法是將以下行添加到.csproj文件中,例如在切換到上面的C#8.0時剛剛插入的LanguageVersion之后:

<NullableReferenceTypes>true</NullableReferenceTypes>

保存.csproj文件并返回到您的程序:發(fā)生了什么?你有兩個警告!每個代表一個功能的“一半”。讓我們依次看看它們。第一個是null這一行:

string s = null;

它抱怨你將null賦給“不可空類型”:啥?!?當(dāng)打開該功能時,在普通的引用類型中不再歡迎使用null,例如string!因?yàn)?#xff0c;你知道嗎,null不是一個字符串!我們一直假裝在過去的五十年在面向?qū)ο缶幊?#xff0c;但實(shí)際上null并不是一個對象:這就是為什么每當(dāng)你試圖將它做為對象時一切都會爆炸!

所以不多說:null是禁止的,除非你要求它。你是怎么要求的?通過使用可空的引用類型,例如string?。尾隨問號表示允許null:

string? s = null;

警告消失了:我們已明確表達(dá)了此變量保持null的意圖,所以現(xiàn)在沒問題了。

直到下一行代碼!在該行:

WriteLine($"The first letter of {s} is {s[0]}");

它抱怨s中s[0],你可能會間接引用一空引用。果然:是!干得好,編譯器!你怎么解決它?嗯,這幾乎取決于你 - 無論何種方式你得修復(fù)它!讓我們嘗試初學(xué)者的方法, 只在s非null時執(zhí)行該行:

if (s != null) WriteLine($"The first letter of {s} is {s[0]}");

警告消失了!為什么?因?yàn)榫幾g器可以看到,只有s不是null時才會走后面的代碼。它實(shí)際上進(jìn)行了全流分析,跟蹤每行代碼中的每個變量,以便密切關(guān)注它可能是null的和可能不是的位置。它會監(jiān)視您的測試和作業(yè),并進(jìn)行簿記(bookkeeping)。

我們試試另一種方法:

WriteLine($"The first letter of {s} is {s?[0] ?? '?'}");

這使用null條件索引運(yùn)算符s?[0],它避免了間接引用,如果s為null ,則生成null。現(xiàn)在我們有一個可空的char?,但是null合并運(yùn)算符?? '?'替換null值為字符 '?'。因此避免了所有null間接引用。編譯器很高興,沒有給出警告。

正如您所看到的,該功能可以讓您在編寫代碼時保持誠實(shí):它會強(qiáng)制您在系統(tǒng)中使用null時通過使用可空的引用類型來表達(dá)您的意圖。并且一旦出現(xiàn)null,它就會強(qiáng)制您負(fù)責(zé)任地處理它,讓您在存在可能間接引用null值以觸發(fā)空引用異常的風(fēng)險時進(jìn)行檢查。

你現(xiàn)在完全null安全了嗎?沒有。有幾種方法可以使null值漏掉并導(dǎo)致空引用異常:

  • 如果你調(diào)用沒有可空的引用類型功能的代碼(也許它是在該功能存在之前編譯的),那么我們無法知道該代碼的意圖是什么:它沒有區(qū)分可空和不可空 - 我們說它是“無視的”。所以我們給它一個通行證; 我們根本不會對此類調(diào)用發(fā)出警告。

  • 分析器本身有一些漏洞。其中大多數(shù)是安全和便利之間的權(quán)衡; 如果我們抱怨,那將很難修復(fù)。例如,當(dāng)你編寫時new string[10],我們創(chuàng)建一個充滿null值的數(shù)組,類型為非null字符串。我們不會對此發(fā)出警告,因?yàn)榫幾g器如何跟蹤您初始化所有數(shù)組元素?

但總的來說,如果你廣泛使用這個功能(即在任何地方打開它),它應(yīng)該照顧絕大多數(shù)的空引用。

毫無疑問地,我們打算在現(xiàn)有代碼上開始使用該功能!一旦打開它,您可能會收到很多警告。其中一些實(shí)際上代表了問題:是的,你發(fā)現(xiàn)了一個錯誤!其中一些可能有點(diǎn)煩人; 你的代碼顯然是null安全的,你只是沒有工具來表達(dá)你的意圖:你沒有可空的引用類型!例如,在我們開始的行:

string s = null;

這在現(xiàn)有代碼中將非常普遍!正如你所看到的那樣,我們也確實(shí)在下一行發(fā)出了警告,我們試圖間接引用它。因此,從安全的角度來看,此處的賦值警告嚴(yán)格來說是多余的:它使您在新代碼中保持誠實(shí),但修復(fù)現(xiàn)有代碼中的所有事件并不會使其更安全。對于這種情況,我們正在處理一種模式,其中某些警告被關(guān)閉,當(dāng)它不影響空安全性時,因此升級現(xiàn)有代碼不那么令人生畏。

另一個有助于升級的功能是,您可以使用編譯器指令#nullable enable和#nullable disable在代碼中“本地”打開或關(guān)閉該功能。這樣你就可以逐步完成你的項(xiàng)目并逐步處理注釋和警告。

要了解更多關(guān)于可空引用類型檢查出Overview of Nullable types和Introduction to nullable tutorial。

為了更深入的設(shè)計理由,去年我在C#中寫了一篇帖子Introducing Nullable Reference Types in C#。

如果您想讓自己沉浸在設(shè)計工作的日常工作中,請查看GitHub上的Language Design Notes,或者Nullable Reference Types Specification。

范圍和索引

使用索引數(shù)據(jù)結(jié)構(gòu)時,C#的表現(xiàn)力越來越強(qiáng)。曾經(jīng)想要簡單的語法來切出數(shù)組,字符串或span的一部分嗎?現(xiàn)在你可以!

繼續(xù)將您的程序更改為以下內(nèi)容:

讓我們來看看迭代名字?jǐn)?shù)組的那段代碼。修改foreach如下:

foreach (var name in names[1..4])

看起來我們正在迭代名字1到4。事實(shí)上代碼運(yùn)行時也確實(shí)如此!終點(diǎn)是排外的,即不包括元素4。1..4實(shí)際上是一個范圍表達(dá)式,它不必像該處一樣,作為索引操作的一部分出現(xiàn)。它有一種自己的類型,叫做Range。如果我們想要的話,我們可以把它拉到自己的變量中,它會起到同樣的作用:

Range range = 1..4; foreach (var name in names[range])

范圍表達(dá)式的終點(diǎn)不必是整數(shù)。事實(shí)上,它們屬于一種類型,叫Index,可由非負(fù)數(shù)轉(zhuǎn)換得來。但是你也可以使用一個新的^運(yùn)算符創(chuàng)建Index,意思是“從末尾”。所以^1是從末尾開始1個:

foreach (var name in names[1..^1])

這會在數(shù)組的每一端去除一個元素,產(chǎn)生一個帶有中間三個元素的數(shù)組。

范圍表達(dá)式可以在任一端或兩端打開。..^1與0..^1相同。1..與1..^0相同。并且..與0..^0相同:從頭到尾。試試吧!嘗試在Range的兩端混合使用“從開始”和“從末尾”的Index,看看會發(fā)生什么。

范圍不僅僅適用于索引器。例如,我們計劃有重載string.SubString,SPan<T>.Slice以及使用Range參數(shù)的AsSpan擴(kuò)展方法。這些不在.NET Core 3.0預(yù)覽中。

異步流

IEnumerable<T>在C#中扮演著特殊的角色。“IEnumerables”代表各種不同的數(shù)據(jù)序列,并且語言具有用于消費(fèi)和生成它們的特殊構(gòu)造。

正如我們在當(dāng)前的程序中看到的那樣,它們通過foreach聲明來消費(fèi),該聲明涉及獲取枚舉器的苦差事,反復(fù)推進(jìn)它,沿途提取元素,最后處理枚舉器。并且可以使用迭代器生成它們:yield return按消費(fèi)者要求產(chǎn)生元素。但兩者都是同步的:當(dāng)結(jié)果被請求時最好已經(jīng)準(zhǔn)備就緒,否則就會阻塞線程!

async和await加入到C#中用來處理當(dāng)結(jié)果被請求時不一定準(zhǔn)備好的情況。它們可以異步await,并且線程可以在其可用之前執(zhí)行其他操作。但這僅適用于單個值,而不適用于隨時間逐漸和異步生成的序列,例如來自IoT傳感器的測量值或來自服務(wù)的流數(shù)據(jù)。

異步流在C#中將異步和枚舉結(jié)合在一起!讓我們看看,通過逐步“異步”我們當(dāng)前的程序。

首先,讓我們在文件的頂部添加另一個using指令:

using System.Threading.Tasks;

現(xiàn)在讓我們通過在yield return名字之前增加一個異步延遲來模擬GetNames做了一些異步工作:

await Task.Delay(1000);yield return name;

當(dāng)然,我們得到了一個錯誤: 只能在async方法中使用await。所以我們讓它異步:

static async IEnumerable<string> GetNames()

現(xiàn)在我們被告知我們沒有為異步方法返回正確的類型,這是公平的。但除了通常的Task東西之外,這次我們的類型列表中有了一個新的候選可以返回:IAsyncEnumerable

static async IAsyncEnumerable<string> GetNames()

就像我們已經(jīng)生成了一個異步字符串流!根據(jù)命名指南,讓我們重命名GetNames為GetNamesAsync。

static async IAsyncEnumerable<string> GetNamesAsync()

現(xiàn)在我們在Main方法中的這一行得到一個錯誤:

foreach (var name in GetNamesAsync())

不知道如何foreach一個IAsyncEnumerable<T>。這是因?yàn)楫惒搅鞯膄oreach需要顯式使用await關(guān)鍵字:

await foreach (var name in GetNamesAsync())

這是foreach的異步版本:采用異步流并等待每個元素!當(dāng)然它只能在異步方法中這樣做,所以我們必須使我們的Main方法異步。幸運(yùn)的是,C#7.2增加了對它的支持:

static async Task Main(string[] args)

現(xiàn)在所有的混亂都消失了,程序是正確的。但是如果你嘗試編譯并運(yùn)行它,你會得到一些令人尷尬的錯誤。那是因?yàn)槲覀兏阍伊艘幌?#xff0c;并沒有完全對齊.NET Core 3.0和Visual Studio 2019的預(yù)覽。具體來說,有一種實(shí)現(xiàn)類型,異步迭代器利用它與編譯器期望的不同。

您可以通過向項(xiàng)目添加單獨(dú)的源文件來修復(fù)此問題,其中包含此橋接代碼。再次編譯,一切都應(yīng)該工作得很好。

下一步

請讓我們知道你的想法!如果您嘗試這些功能并了解如何改進(jìn)它們,請使用Visual Studio 2019預(yù)覽中的反饋按鈕。預(yù)覽的整個目的是根據(jù)現(xiàn)實(shí)用戶手中的功能如何進(jìn)行最后一次校正,所以請告訴我們!

原文地址:https://www.cnblogs.com/waku/p/10094691.html


.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

總結(jié)

以上是生活随笔為你收集整理的[翻译]初试C# 8.0的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。