国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

一文透徹詳解.NET框架類型系統(tǒng)設(shè)計(jì)要點(diǎn)

瀏覽:143日期:2022-06-14 14:54:13
目錄引言.NET 設(shè)計(jì)要點(diǎn).NET 堆棧的支柱類型系統(tǒng)自動內(nèi)存管理▌Bump 指針分配▌分代收集▌壓縮▌并行▌并發(fā)▌固定▌獨(dú)立 GC▌診斷安全錯(cuò)誤處理并發(fā)反射編譯后的二進(jìn)制格式代碼生成互操作二進(jìn)制分布概括引言

自從我們啟動快速發(fā)展的 .NET 開源和跨平臺項(xiàng)目以來,.NET 發(fā)生了很大變化。我們重新思考并完善了該平臺,添加了專為性能和安全性而設(shè)計(jì)的新低級功能,以及以生產(chǎn)力為中心的高級功能。Span<T>、硬件內(nèi)在函數(shù)和可為空的引用類型都是示例。我們正在啟動一個(gè)新的“.NET 設(shè)計(jì)要點(diǎn)”系列文章,以探索定義當(dāng)今 .NET 平臺的基礎(chǔ)知識和設(shè)計(jì)選擇,以及它們?nèi)绾问鼓F(xiàn)在編寫的代碼受益。

本系列的第一篇文章全面概述了平臺的支柱和設(shè)計(jì)要點(diǎn)。當(dāng)您選擇 .NET 時(shí),它在基礎(chǔ)級別上描述了“您得到了什么”,旨在成為一個(gè)充分且以事實(shí)為中心的框架,您可以使用它來向其他人描述該平臺。后續(xù)帖子將更詳細(xì)地介紹這些相同的主題,因?yàn)檫@篇帖子并沒有完全公正地介紹這些功能中的任何一個(gè)。這篇文章不描述工具,如 Visual Studio,也不涵蓋更高級的庫和應(yīng)用程序模型,如 ASP.NET Core 提供的那些。

我們所說的“.NET”是現(xiàn)代的 .NET Core。我們在 GitHub 上作為開源項(xiàng)目于2014年啟動了這個(gè)項(xiàng)目。它在 Arm64、x64 和其他芯片架構(gòu)上的 Linux、macOS 和 Windows 上運(yùn)行。它在一堆 Linux 發(fā)行版中可用。它與 .NET Framework 保持了很大的兼容性,但又是一個(gè)全新的方向和產(chǎn)品。

.NET 設(shè)計(jì)要點(diǎn)

.NET 平臺代表生產(chǎn)力、性能、安全性和可靠性。.NET 在這些價(jià)值之間取得的平衡使其具有吸引力。

.NET 的設(shè)計(jì)要點(diǎn)可以歸結(jié)為在安全域(一切都高效)和不安全域(存在大量功能)中都有效和高效。.NET 可能是具有最多內(nèi)置功能的托管環(huán)境,同時(shí)還提供最低的與外部世界互操作的成本,并且兩者之間沒有權(quán)衡。事實(shí)上,許多功能都利用了這種無縫劃分,在底層操作系統(tǒng)和 CPU 的原始能力和功能上構(gòu)建安全的托管 API。

我們可以進(jìn)一步擴(kuò)展設(shè)計(jì)點(diǎn):

生產(chǎn)力是跨運(yùn)行時(shí)、庫、語言和工具的首要設(shè)計(jì)考慮因素。安全代碼是主要的計(jì)算模型,而不安全代碼支持額外的手動優(yōu)化。支持靜態(tài)和動態(tài)代碼,支持廣泛的不同場景。本機(jī)代碼互操作和硬件內(nèi)在函數(shù)成本低且保真度高(原始 API 和指令訪問)。代碼可跨平臺(操作系統(tǒng)、芯片架構(gòu))移植,而平臺定位則支持專業(yè)化和優(yōu)化。通過通用編程模型的專門實(shí)現(xiàn),可以實(shí)現(xiàn)跨編程域(云、客戶端、游戲)的適應(yīng)性。OpenTelemetry 和 gRPC 等行業(yè)標(biāo)準(zhǔn)優(yōu)于定制解決方案。.NET 堆棧的支柱

運(yùn)行時(shí)、庫和語言是 .NET 堆棧的支柱。更高級別的組件,如 .NET 工具和應(yīng)用程序堆棧,如 ASP.NET Core,構(gòu)建在這些支柱之上。這些支柱具有共生關(guān)系,由一個(gè)團(tuán)隊(duì)(Microsoft 員工和開源社區(qū))共同設(shè)計(jì)和構(gòu)建,致力于這些組件的多個(gè)方面并為其提供信息。

C# 是面向?qū)ο蟮?,運(yùn)行時(shí)支持面向?qū)ο?。C# 需要垃圾收集,運(yùn)行時(shí)提供跟蹤垃圾收集器。事實(shí)上,將 C#(以其完整形式)移植到?jīng)]有垃圾收集的系統(tǒng)是不可能的。這些庫(以及應(yīng)用程序堆棧)將這些功能塑造成概念和對象模型,使開發(fā)人員能夠在直觀的工作流程中高效地編寫算法。

C# 是一種現(xiàn)代的、安全的、通用的編程語言,涵蓋了從面向數(shù)據(jù)的記錄等高級功能到函數(shù)指針等低級功能。它提供靜態(tài)類型以及類型和內(nèi)存安全作為基準(zhǔn)功能,同時(shí)提高開發(fā)人員的工作效率和代碼安全性。C# 編譯器也是可擴(kuò)展的,支持插件模型,使開發(fā)人員能夠通過額外的診斷和編譯時(shí)代碼生成來增強(qiáng)系統(tǒng)。

許多 C# 功能已經(jīng)影響或受最先進(jìn)的編程語言的影響。例如,C# 是第一個(gè)引入 async?and?await.?同時(shí),C# 借鑒了其他編程語言中首先引入的概念,例如采用模式匹配和主構(gòu)造函數(shù)等函數(shù)式方法。

核心庫公開了數(shù)千種類型,其中許多類型與 C# 語言集成并為其提供動力。例如,C# 的 foreach 支持枚舉任意集合,基于模式的優(yōu)化使 List<T>?等集合能夠被簡單高效地處理。資源管理可能留給垃圾收集,但可以通過 IDisposable?和 using 中的直接語言支持進(jìn)行快速清理。

C# 中的字符串插值既富有表現(xiàn)力又高效,與 string 、StringBuilder 和 Span<T> 等跨核心庫類型的實(shí)現(xiàn)集成并受其支持。語言集成查詢 (LINQ)功能由庫中的數(shù)百個(gè)序列處理例程提供支持,例如 Where、Select 和 GroupBy,具有支持內(nèi)存中和遠(yuǎn)程數(shù)據(jù)源的可擴(kuò)展設(shè)計(jì)和實(shí)現(xiàn)。從壓縮到密碼學(xué)再到正則表達(dá)式,列表還在繼續(xù),直接集成到語言中的內(nèi)容只是作為核心 .NET 庫的一部分公開的功能的表面。一個(gè)全面的從套接字到 HTTP/3 的網(wǎng)絡(luò)堆棧是一個(gè)獨(dú)立的領(lǐng)域。同樣,庫支持處理無數(shù)格式和語言,如 JSON、XML 和 tar。

.NET 運(yùn)行時(shí)最初稱為“公共語言運(yùn)行時(shí) (CLR)”。它繼續(xù)支持多種語言,一些由 Microsoft 維護(hù)(例如 C#、F#、Visual Basic、C++/CLI 和 PowerShell),一些由其他組織維護(hù)(例如 Cobol、Java、PHP、Python、Scheme)。許多改進(jìn)與語言無關(guān),這會引發(fā)所有改善。

接下來,我們將看看它們一起提供的各種平臺特性。我們可以分別詳細(xì)說明這些組件中的每一個(gè),但您很快就會看到它們在交付 .NET 設(shè)計(jì)點(diǎn)方面進(jìn)行合作。讓我們從類型系統(tǒng)開始。

類型系統(tǒng)

.NET 類型系統(tǒng)提供了顯著的廣度,大致同等地滿足了安全性、描述性、動態(tài)性和本機(jī)互操作性。

首先,類型系統(tǒng)支持面向?qū)ο蟮木幊棠P?。它包括類型、(單個(gè)基類)繼承、接口(包括默認(rèn)方法實(shí)現(xiàn))和虛擬方法分派,為面向?qū)ο笤试S的所有類型分層提供合理的行為。

泛型是一種普遍的特性,它允許將類專門化為一種或多種類型。例如,List<T>?是一個(gè)開放的通用類,而像?List<string>?和?List<int>?這樣的實(shí)例化避免了對單獨(dú)的?ListOfString?和?ListOfInt?類的需要,或者像 ArrayList 那樣依賴 object 和強(qiáng)制轉(zhuǎn)換。泛型還可以跨不同類型創(chuàng)建有用的系統(tǒng)(并減少對大量代碼的需求),例如 Generic Math。

Delegates?和?lambdas?允許將方法作為數(shù)據(jù)傳遞,這使得將外部代碼集成到另一個(gè)系統(tǒng)擁有的操作流中變得容易。它們是一種“膠水代碼”,它們的簽名通常是通用的,可以廣泛使用。

app.MapGet('/Product/{id}', async (int id) => { if (await IsProductIdValid(id)) { return await GetProductDetails(id); } return Products.InvalidProduct; });

這種對 lambdas 的使用是?ASP.NET Core Minimal APIs 的一部分。它可以直接向路由系統(tǒng)提供端點(diǎn)實(shí)現(xiàn)。在更新的版本中,ASP.NET Core 更廣泛地使用了類型系統(tǒng)。

與 .NET 的 GC 管理類型相比,值類型和堆棧分配的內(nèi)存塊提供了對數(shù)據(jù)和本機(jī)平臺互操作的更直接、低級別的控制。.NET 中的大多數(shù)原始類型,如整數(shù)類型,都是值類型,用戶可以定義自己具有相似語義的類型。

.NET 的泛型系統(tǒng)完全支持值類型,這意味著像 List<T>?這樣的泛型類型可以提供值類型集合的平坦、無開銷的內(nèi)存表示。此外,.NET 泛型在替換值類型時(shí)提供專門的編譯代碼,這意味著這些泛型代碼路徑可以避免昂貴的 GC 開銷。

byte magicSequence = 0b1000_0001; Span<byte> data = stackalloc byte[128]; DuplicateSequence(data[0..4], magicSequence);

此代碼生成堆棧分配的值。Span<byte>?是 byte* 的安全和更豐富的版本,提供長度值(帶邊界檢查)和方便的跨度切片。

Ref?類型和變量是一種小型編程模型,它提供對類型系統(tǒng)數(shù)據(jù)的較低級別和更輕量級抽象。這包括 Span<T>。此編程模型不是通用的,包括維護(hù)安全的重要限制。

internal readonly ref T _reference;

這種使用 ref 導(dǎo)致將指針復(fù)制到底層存儲,而不是復(fù)制該指針引用的數(shù)據(jù)。默認(rèn)情況下,值類型是“按值復(fù)制”。ref 提供“按引用復(fù)制”行為,可以提供顯著的性能優(yōu)勢。

自動內(nèi)存管理

.NET 運(yùn)行時(shí)通過垃圾收集器 (GC) 提供自動內(nèi)存管理。對于任何語言,其內(nèi)存管理模型可能是其最具決定性的特征。.NET 語言也是如此。

工程師花費(fèi)數(shù)周甚至數(shù)月的時(shí)間來追蹤這些問題的情況并不少見。許多語言使用垃圾收集器作為消除這些錯(cuò)誤的用戶友好方式,因?yàn)?GC 確保正確的對象生命周期。通常,GC 會分批釋放內(nèi)存以高效運(yùn)行。這會導(dǎo)致暫停,如果您對延遲要求非常嚴(yán)格,這可能不適合,并且內(nèi)存使用率會更高。GC 往往具有更好的內(nèi)存局部性,并且某些 GC 能夠壓縮堆,使其不易產(chǎn)生內(nèi)存碎片。

.NET 具有自我調(diào)整、跟蹤 GC。它旨在一般情況下提供“放手”操作,同時(shí)為更極端的工作負(fù)載提供配置選項(xiàng)。GC 是多年投資、改進(jìn)和從多種工作負(fù)載中學(xué)習(xí)的結(jié)果。

▌Bump 指針分配

通過指針遞增所需的大小分配對象(而不是在分離的空閑塊中尋找空間),因此一起分配的對象往往會在一起。由于用戶經(jīng)常一起訪問不同對象,這樣做可以實(shí)現(xiàn)更好的內(nèi)存局部性 memory locality ,這有利于保證性能。

▌分代收集

對象生命周期遵循分代假設(shè) generational hypothesis 是非常常見的,對象生存周期要么很長,要么很短。因此,對于 GC 來說,如果大部分運(yùn)行時(shí)只收集臨時(shí)對象占用的內(nèi)存(稱為臨時(shí) GC ),而不是每次運(yùn)行時(shí)都必須收集整個(gè)堆(稱為完整 GC ),那么效率就要高得多。

▌壓縮

相同數(shù)量的可用空間在面積大而數(shù)量少的塊中比在面積小和數(shù)量多的塊中更有用。在壓縮 GC 期間,仍然存在的對象會被移動到一起,由此可以形成更大的自由空間。這種行為需要比非移動 GC 更復(fù)雜的實(shí)現(xiàn),因?yàn)樗枰聦@些移動對象的引用。.NET GC 被動態(tài)調(diào)整為僅在確定回收的內(nèi)存高于 GC 成本時(shí)才執(zhí)行壓縮。這意味著臨時(shí)集合通常會被壓縮。

▌并行

GC 工作可以在單個(gè)線程或多個(gè)線程上運(yùn)行。Workstation flavor 在單個(gè)線程上進(jìn)行 GC,而 Server flavor 在多個(gè) GC 線程上進(jìn)行,這樣可以更快結(jié)束作業(yè)。服務(wù)器 GC 還可以適應(yīng)更大的分配率,因?yàn)橛卸鄠€(gè)堆供應(yīng)用程序分配,因此它對吞吐量適應(yīng)性也很好。

▌并發(fā)

在用戶線程暫停時(shí)進(jìn)行 GC 工作稱為 Stop-The-World,這樣使實(shí)現(xiàn)需求更簡單,但這些暫??赡軐τ?GC 來說是不可接受的。.NET 提供 concurrent flavor 來緩解該問題。

▌固定

.NET GC 支持對象固定,它可以實(shí)現(xiàn)與本機(jī)代碼的零拷貝互操作。此功能可實(shí)現(xiàn)高性能和高保真度的本機(jī)互操作,同時(shí)限制 GC。

▌獨(dú)立 GC

可以使用具有不同機(jī)制的獨(dú)立 GC(通過配置指定并滿足 interface requirements)。這樣一來,調(diào)查和嘗試新功能就更容易了。

▌診斷

GC 提供有關(guān)內(nèi)存和集合的大量信息,這允許您將數(shù)據(jù)與系統(tǒng)的其余部分相關(guān)聯(lián)。例如,您可以通過捕獲 GC 事件并將它們與其他事件(如 IO)相關(guān)聯(lián)來評估 GC impact of your tail latency 尾部延遲對 GC 的影響,以計(jì)算 GC 對其他因素的影響程度,這樣您就可以將精力集中在正確的組件上。

安全

.NET 編程安全一直是過去十年的熱門話題之一。它是 .NET 等托管環(huán)境的固有組件。

安全形式:

Type safety 類型安全 — 不能使用任意類型代替另一個(gè)類型,避免未定義的行為。Memory safety 內(nèi)存安全 — 不能使用任意類型代替另一個(gè)類型,避免未定義的行為。Concurrency or thread safety 并發(fā)或線程安全 — 不能使用任意類型代替另一個(gè)類型,避免未定義的行為。

.NET 從最初的設(shè)計(jì)開始就被設(shè)計(jì)成一個(gè)保證安全的平臺。特別需要指出的是,它旨在啟用新一代 Web 服務(wù)器,這些服務(wù)器一直需要在世界上復(fù)雜的計(jì)算環(huán)境(Internet)中接受不受信任的輸入的考驗(yàn)?,F(xiàn)在普遍認(rèn)為網(wǎng)絡(luò)程序應(yīng)該用安全的語言編寫。

類型安全由語言和運(yùn)行時(shí)模塊同時(shí)強(qiáng)制執(zhí)行。編譯器驗(yàn)證靜態(tài)不變量,例如分配不同的類型——例如,分配 string 給 Stream——這將導(dǎo)致編譯器中產(chǎn)生錯(cuò)誤。運(yùn)行時(shí)驗(yàn)證動態(tài)不變量,例如不同類型之間的轉(zhuǎn)換,就將產(chǎn)生 InvalidCastException。

內(nèi)存安全主要由代碼生成器(如 JIT)和垃圾收集器合作實(shí)現(xiàn)。變量引用值要么是活動對象,要么是 null,要么超出范圍。默認(rèn)情況下內(nèi)存是自動初始化的,這樣新對象就不會使用未初始化的內(nèi)存。邊界檢查禁止訪問數(shù)組中無效索引的元素讀取未定義的內(nèi)存——通常由一個(gè)單位的錯(cuò)誤偏移引起——這會導(dǎo)致 IndexOutOfRangeException。

Cnull 處理是保證內(nèi)存安全的一種特殊形式??煽找妙愋?Nullable reference types 是一種 C# 語言和編譯器功能,可靜態(tài)標(biāo)識未安全處理的代碼 null。特別是,如果您取消引用可能為 null 的變量,編譯器會發(fā)出警告。您還可以禁止 null 賦值,這樣編譯器會在您可能給變量賦空值時(shí)發(fā)出警告。運(yùn)行時(shí)具有匹配的動態(tài)驗(yàn)證功能,可通過拋出 NullReferenceException 來防止引用被訪問。

C# 功能依賴于庫中可為空的屬性 nullable attributes 。它還依賴于它們在庫和應(yīng)用程序堆棧(我們已經(jīng)完成)中的詳盡應(yīng)用,以便為您的代碼提供來自靜態(tài)分析工具的準(zhǔn)確結(jié)果。

.NET 中沒有內(nèi)置的并發(fā)安全。相反,開發(fā)人員需要遵循模式和約定來避免未定義的行為。.NET 生態(tài)系統(tǒng)中還有分析器和其他工具,可以深入了解并發(fā)問題。核心庫包括多種可以安全并發(fā)使用的類型和方法,例如支持任意數(shù)量的并發(fā)讀取器和寫入器而不會冒數(shù)據(jù)結(jié)構(gòu)損壞風(fēng)險(xiǎn)的 concurrent collections 并發(fā)集合。

運(yùn)行時(shí)公開安全和 unsafe code 不安全的代碼模型。安全代碼的安全性得到保證,這是默認(rèn)設(shè)置,而開發(fā)人員必須選擇使用不安全代碼。不安全代碼通常用于與底層平臺互操作、與硬件交互或?qū)π阅荜P(guān)鍵路徑實(shí)施手動優(yōu)化。

沙箱 sandbox 是一種特殊的安全形式,它提供隔離并限制組件之間的訪問。我們依賴標(biāo)準(zhǔn)的隔離技術(shù),如進(jìn)程(和 CGroups)、虛擬機(jī)和 WebAssembly(具有不同的特性)。

錯(cuò)誤處理

異常是 .NET 中的主要錯(cuò)誤處理模型。異常的好處是錯(cuò)誤信息不需要在方法簽名中表示或由每個(gè)方法處理。

下面的代碼演示了一個(gè)典型的模式:

try{ var lines = await File.ReadAllLinesAsync(file); Console.WriteLine($'The {file} has {lines.Length} lines.');}catch (Exception e) when (e is FileNotFoundException or DirectoryNotFoundException){ Console.WriteLine($'{file} doesn't exist.');}

正確的異常處理對于應(yīng)用程序的可靠性至關(guān)重要??梢栽谟脩舸a中有意處理預(yù)期的異常,否則應(yīng)用程序就會崩潰。崩潰的應(yīng)用程序比具有未定義行為的應(yīng)用程序更可靠。當(dāng)您想找出問題的根本原因時(shí),它也更容易診斷。

異常從錯(cuò)誤點(diǎn)拋出,并自動收集有關(guān)程序狀態(tài)的附加診斷信息。這些信息可用于交互式調(diào)試、應(yīng)用程序可觀察性和事后調(diào)試。這些診斷方法中的每一種都依賴于訪問大量的錯(cuò)誤信息和應(yīng)用程序狀態(tài)來診斷問題。

異常是為罕見的情況而設(shè)計(jì)的。這在一定程度上是因?yàn)樗鼈兊男阅艹杀鞠鄬^高。它們不打算用于控制流,即使它們有時(shí)以這種方式使用。

異常(有一部分)依賴于取消。一旦觀察到取消請求,它們就可以有效地停止執(zhí)行并展開正在進(jìn)行的調(diào)用堆棧。

try { await source.CopyToAsync(destination, cancellationToken); } catch (OperationCanceledException) { Console.WriteLine('Operation was canceled'); }

.NET 設(shè)計(jì)模式包括替代形式的錯(cuò)誤處理,以應(yīng)對異常的性能成本過高的情況。例如,int.TryParse 返回成功時(shí)其參數(shù)包含已解析的有效整數(shù),Dictionary<TKey, TValue>.TryGetValue 提供了一個(gè)類似的模型,返回一個(gè)有效 TValue 類型作為案例中的參數(shù)等。

錯(cuò)誤處理和更普遍的診斷是通過低級運(yùn)行時(shí) API、higher-level libraries 和 tools 實(shí)現(xiàn)的。這些功能旨在支持更新的部署選項(xiàng),例如容器。例如,dotnet-monitor 可以通過內(nèi)置的面向診斷的 Web 服務(wù)器將運(yùn)行時(shí)數(shù)據(jù)從應(yīng)用導(dǎo)出到偵聽器。

并發(fā)

支持同時(shí)做多件事是幾乎所有工作負(fù)載的基礎(chǔ),無論是在保持 UI 響應(yīng)的同時(shí)進(jìn)行后臺處理的客戶端應(yīng)用程序、處理成千上萬同時(shí)請求的服務(wù)、響應(yīng)大量同時(shí)刺激的設(shè)備,還是高驅(qū)動的機(jī)器并行處理計(jì)算密集型操作。操作系統(tǒng)通過線程為這種并發(fā)性提供支持,這使得多個(gè)指令流能夠獨(dú)立處理,操作系統(tǒng)管理這些線程在機(jī)器中任何可用處理器內(nèi)核上的執(zhí)行。操作系統(tǒng)還提供對執(zhí)行 I/O 的支持,提供的機(jī)制使 I/O 能夠以可擴(kuò)展的方式執(zhí)行,并且在任何特定時(shí)間都有許多“運(yùn)行中”的 I/O 操作。

.NET 通過庫和深度集成到 C# 中,在多個(gè)抽象級別提供此類并發(fā)和并行化支持。線程 Thread 類位于層次結(jié)構(gòu)的底部,代表一個(gè)操作系統(tǒng)線程,使開發(fā)人員能夠創(chuàng)建新線程并隨后加入它們。線程池 ThreadPool 位于線程之上,允許開發(fā)人員考慮異步安排在線程池上運(yùn)行的工作項(xiàng),并這些線程的管理(包括從池中添加和刪除線程,以及為這些線程分配工作項(xiàng))放在運(yùn)行時(shí)。Task 然后為任何異步執(zhí)行的操作提供統(tǒng)一的表示形式,并且可以通過多種方式創(chuàng)建和連接;例如,Task.Run 允許在 ThreadPool 上運(yùn)行安排委托并返回 Task 以表示該工作的最終完成,同時(shí) Socket.ReceiveAsync 返回一個(gè)Task<int>(或 ValueTask<int>)表示異步 I/O 的最終完成,提供了大量的同步原語,用于協(xié)調(diào)線程和異步操作之間的同步和異步活動,并提供了大量高級 API 以簡化常見并發(fā)模式的實(shí)現(xiàn),例如,SocketParallel.ForEach 和 Parallel.ForEachAsync 使處理一個(gè)線程的所有元素變得更容易實(shí)現(xiàn)數(shù)據(jù)序列并行。

異步編程支持也是 C# 編程語言的一流功能,它提供了 async 和 await 關(guān)鍵字,使編寫和組合異步操作變得容易,同時(shí)仍然享受該語言必須提供的所有控制流結(jié)構(gòu)的全部好處。

反射

反射是一種“程序即數(shù)據(jù)”范例,它能讓程序的一部分根據(jù)程序集、類型和成員動態(tài)查詢和/或調(diào)用另一部分。它對于后期綁定編程模型和工具特別有用。

以下代碼使用反射來查找和調(diào)用 type。

foreach (Type type in typeof(Program).Assembly.DefinedTypes) { if (type.IsAssignableTo(typeof(IStory)) && !type.IsInterface) { IStory? story = (IStory?)Activator.CreateInstance(type); if (story is not null) { var text = story.TellMeAStory(); Console.WriteLine(text); } } } interface IStory { string TellMeAStory(); } class BedTimeStore : IStory { public string TellMeAStory() => 'Once upon a time, there was an orphan learning magic ...'; } class HorrorStory : IStory { public string TellMeAStory() => 'On a dark and stormy night, I heard a strange voice in the cellar ...'; }

此代碼動態(tài)枚舉實(shí)現(xiàn)特定接口的所有程序集類型,實(shí)例化每個(gè)類型的實(shí)例,并通過該接口調(diào)用對象的方法。代碼本來可以靜態(tài)編寫的,因?yàn)樗徊樵兯玫某绦蚣械念愋停@樣做,需要將所有實(shí)例的集合(也許是作為一個(gè) List<IStory>)交給它來處理。如果此算法從加載項(xiàng)目錄加載任意程序集,則更有可能使用這種后期綁定方法。有這樣一種情況:您無法提前獲取程序集和類型,反射通常就被用在這樣的場景中。

反射可能是 .NET 中提供的最動態(tài)的系統(tǒng)。它旨在使開發(fā)人員能夠創(chuàng)建自己的二進(jìn)制代碼加載器和方法分派器,其語義可以與靜態(tài)代碼策略(由運(yùn)行時(shí)定義)相匹配或有所區(qū)別。反射公開了一個(gè)豐富的對象模型,它可以直接用于簡單的用例,但隨著場景變得更加復(fù)雜,您就需要更深入地了解 .NET 類型系統(tǒng)。

反射還啟用了一種單獨(dú)的模式,其中生成的 IL 字節(jié)代碼可以在運(yùn)行時(shí)進(jìn)行 JIT 編譯,有時(shí)用于以專用算法替換通用算法。有了對象模型和其他細(xì)節(jié),它通常會被用于序列化器或?qū)ο箨P(guān)系映射器中。

編譯后的二進(jìn)制格式

應(yīng)用程序和庫被編譯為 PE/COFF 格式的標(biāo)準(zhǔn)化跨平臺字節(jié)碼。二進(jìn)制分發(fā)最重要的是性能特征。它使應(yīng)用程序能夠擴(kuò)展到越來越多的項(xiàng)目。每個(gè)庫都包含一個(gè)導(dǎo)入和導(dǎo)出類型的數(shù)據(jù)庫,稱為元數(shù)據(jù),它對開發(fā)操作和運(yùn)行應(yīng)用程序都起著重要作用。

編譯的二進(jìn)制文件包括兩個(gè)主要方面:

二進(jìn)制字節(jié)碼——簡潔而規(guī)則的格式,無需在高級語言編譯器(如 C#)編譯后解析文本源。元數(shù)據(jù)——描述導(dǎo)入和導(dǎo)出的類型,包括給定方法的字節(jié)代碼的位置。

例如,對于開發(fā),工具可以有效地讀取元數(shù)據(jù)以確定給定庫公開的類型集以及哪些類型實(shí)現(xiàn)了某些接口。此過程可加快編譯速度,并使 IDE 和其他工具能夠準(zhǔn)確呈現(xiàn)給定上下文的類型和成員列表。

對于運(yùn)行時(shí),元數(shù)據(jù)使庫能夠延遲加載,方法體更是如此。上文討論過的反射是元數(shù)據(jù)和 IL 的運(yùn)行時(shí) API。還有其他更適合工具的 API。

隨著時(shí)間的推移,IL 格式一直保持向后兼容。最新的 .NET 版本仍然可以加載和執(zhí)行由 .NET Framework 1.0 編譯器生成的二進(jìn)制文件。

共享庫通常通過 NuGet 包分發(fā)。默認(rèn)情況下,帶有單個(gè)二進(jìn)制文件的 NuGet 包可以在任何操作系統(tǒng)和體系結(jié)構(gòu)上運(yùn)行,但也可以專門用于在特定環(huán)境中提供特定行為。

代碼生成

.NET 字節(jié)碼不是機(jī)器可執(zhí)行的格式,它需要通過某種形式的代碼生成器使其可執(zhí)行。這可以通過提前 (AOT) 編譯、即時(shí) (JIT) 編譯、解釋或轉(zhuǎn)譯來實(shí)現(xiàn)。事實(shí)上,這些都是今天在各種場景中使用的。

.NET 以 JIT 編譯而聞名。JIT 在應(yīng)用程序運(yùn)行時(shí)將方法(和其他成員)編譯為本機(jī)代碼,并且僅在需要時(shí)才將其編譯,因此得名“及時(shí)(just in time,縮寫為 JIT)”。例如,一個(gè)程序在運(yùn)行時(shí)可能只調(diào)用一種類型中幾種方法中的一種。JIT 還可以利用僅在運(yùn)行時(shí)可用的信息,如初始化的只讀靜態(tài)變量的值或程序運(yùn)行的確切 CPU 模型,并且可以多次編譯相同的方法,以便每次針對不同的目標(biāo)進(jìn)行優(yōu)化,并從以前的編譯中吸取教訓(xùn)。

JIT 為給定的操作系統(tǒng)和芯片架構(gòu)生成代碼。.NET 具有支持 Arm64 和 x64 指令集以及 Linux、macOS 和 Windows 操作系統(tǒng)等的 JIT 實(shí)現(xiàn)。作為 .NET 開發(fā)人員,您不必?fù)?dān)心 CPU 指令集和操作系統(tǒng)調(diào)用約定之間的差異。JIT 負(fù)責(zé)生成 CPU 需要的代碼。它還知道如何為每個(gè) CPU 生成快速代碼,操作系統(tǒng)和 CPU 供應(yīng)商經(jīng)常幫助我們做到這一點(diǎn)。

AOT 類似,只是代碼是在程序運(yùn)行之前生成的。開發(fā)人員選擇 AOT 是因?yàn)樗梢酝ㄟ^消除 JIT 完成的工作來顯著縮短啟動時(shí)間。AOT 構(gòu)建的應(yīng)用程序本質(zhì)上是特定于操作系統(tǒng)和體系結(jié)構(gòu)的,這意味著需要額外的步驟才能使應(yīng)用程序在多個(gè)環(huán)境中運(yùn)行。例如,如果您想支持 Linux 和 Windows 以及 Arm64 和 x64,那么您需要構(gòu)建四個(gè)變體(以支持所有組合)。AOT 代碼也可以提供有價(jià)值的優(yōu)化,但總體不如 JIT 多。

代碼生成器優(yōu)化之一是內(nèi)在函數(shù)。硬件內(nèi)在函數(shù)就是 .NET API 直接轉(zhuǎn)換為 CPU 指令的例子。這已在整個(gè) .NET 庫中普遍用于 SIMD 指令。

互操作

.NET 被特意設(shè)計(jì)用于與本機(jī)庫的低成本互操作。.NET 程序和庫可以無縫調(diào)用低級操作系統(tǒng) API 或利用 C/C++ 庫的龐大生態(tài)系統(tǒng)?,F(xiàn)代 .NET 運(yùn)行時(shí)專注于提供低級互操作構(gòu)建塊,例如通過函數(shù)指針調(diào)用本機(jī)方法的能力,將托管方法公開為非托管回調(diào)或自定義接口轉(zhuǎn)換。.NET 也在這個(gè)領(lǐng)域不斷發(fā)展,在 .NET 7 中發(fā)布了源代碼生成的解決方案,進(jìn)一步減少了開銷并且便于使用 AOT。

下面的代碼演示了 C# 函數(shù)指針的效率。

// Using a function pointer avoids a delegate allocation. // Equivalent to `void (*fptr)(int) = &Callback;` in C delegate* unmanaged<int, void> fptr = &Callback; RegisterCallback(fptr); [UnmanagedCallersOnly] static void Callback(int a) => Console.WriteLine($'Callback: {a}'); [LibraryImport('...', EntryPoint = 'RegisterCallback')] static partial void RegisterCallback(delegate* unmanaged<int, void> fptr);

此示例使用 .NET 7 中引入的 LibraryImport 源代碼生成器。它位于現(xiàn)有 DllImport 或 P/Invoke 功能之上。

獨(dú)立包通過利用這些低級構(gòu)建塊(例如 ClangSharp、Xamarin.iOS 和 Xamarin.Mac、CsWinRT、CsWin32 和 DNNE?)提供更高級別的特定于域的互操作解決方案。

這些新功能并不意味著內(nèi)置運(yùn)行時(shí)托管/非托管編組或 Windows COM 互操作等內(nèi)置互操作解決方案沒有用——我們知道它們有用,而且人們已經(jīng)開始依賴它們。那些之前內(nèi)置到運(yùn)行時(shí)中的功能將繼續(xù)按原樣提供支持,只是為了向后兼容,我們沒有進(jìn)一步發(fā)展它們的計(jì)劃。所有未來的投資都將集中在互操作構(gòu)建塊以及它們支持的特定領(lǐng)域和更高性能的解決方案上。

二進(jìn)制分布

Microsoft 的 .NET 團(tuán)隊(duì)維護(hù)著多個(gè)二進(jìn)制發(fā)行版,最近開始支持 Android、iOS 和 WebAssembly。該團(tuán)隊(duì)使用多種技術(shù)為這些環(huán)境中的每一個(gè)環(huán)境定制代碼庫。大多數(shù)平臺是用 C# 編寫的,這使得移植可以集中在相對較小的組件集上。

社區(qū)維護(hù)著另一套發(fā)行版,主要集中于 Linux 。例如,.NET 已包含在?Alpine Linux、Fedora、Red Hat Enterprise Linux 和 Ubuntu中。

概括

我們有幾個(gè)版本進(jìn)入現(xiàn)代 .NET 時(shí)代,最近發(fā)布了 .NET 7。我們認(rèn)為,如果我們總結(jié)自 .NET Core 1.0 以來我們一直在平臺的最低級別構(gòu)建的內(nèi)容,將會很有用。我們明確保留了原始 .NET 的精神,結(jié)果是一個(gè)新平臺開辟了一條新道路,并為開發(fā)人員提供了新的和更多的價(jià)值。

讓我們用最開始的話題結(jié)束本篇文章。.NET 代表四個(gè)值:生產(chǎn)力、性能、安全性和可靠性。我們堅(jiān)信,當(dāng)不同的語言平臺提供不同的方法時(shí),開發(fā)人員會得到最好的服務(wù)。作為一個(gè)團(tuán)隊(duì),我們尋求為 .NET 開發(fā)人員提供高生產(chǎn)力,同時(shí)提供在性能、安全性和可靠性方面處于領(lǐng)先地位的平臺。

這篇文章由 Jan Kotas、Rich Lander、Maoni Stephens 和 Stephen Toub 撰寫,囊括了 .NET 團(tuán)隊(duì)同事的深刻見解和審閱。

以上就是一文透徹詳解.NET框架類型系統(tǒng)設(shè)計(jì)要點(diǎn)的詳細(xì)內(nèi)容,更多關(guān)于.NET 框架類型系統(tǒng)的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: ASP.NET
主站蜘蛛池模板: 男女扒开双腿猛进入免费网站 | 分享一个无毒不卡免费国产 | 97免费视频观看 | 亚洲一区二区三区高清视频 | 色老久久精品偷偷鲁一区 | 私人毛片免费高清影视院丶 | 中国a级淫片免费播放 | 伊人狠狠丁香婷婷综合色 | 国产精品久久久久久久久久久威 | 国产亚洲亚洲精品777 | www日本com | 一级毛片观看 | 亚洲精品国产成人中文 | 国产成人午夜片在线观看 | 欧美中文字幕一区二区三区 | 亚洲精品线在线观看 | 日韩国产欧美成人一区二区影院 | 92精品国产自产在线 | 亚洲成人自拍网 | 又黄又骚| 九九全国免费视频 | 久久精品国产精品亚洲人人 | 性生i活一级一片 | 国产成人精品综合久久久软件 | 成年人福利视频 | 亚洲美女视频在线 | 韩国一级永久免费观看网址 | 最新中文字幕一区二区乱码 | 免费一级a毛片在线播放视 免费一级α片在线观看 | 97视频免费观看 | xxx免费视频 | 9lporm自拍视频在线 | 久草日韩 | 最新毛片久热97免费精品视频 | 久久不见久久见免费影院www日本 | 男人女人做性全程视视频 | 性色欧美xo影院 | 亚洲天堂网在线播放 | 手机看片神马午夜 | 久久国产精品久久久久久久久久 | 五月色一区二区亚洲小说 |