解析:從CLR到現(xiàn)代語言特性)
1. 從零開始為什么是C#和.NET如果你剛拿到一本《C#圖解教程》翻開第一章看到“C#和.NET框架”這個(gè)標(biāo)題可能會(huì)覺得有點(diǎn)抽象。這章到底在講什么簡(jiǎn)單來說它是在為你即將開始的C#編程之旅繪制一張“世界地圖”。在你學(xué)習(xí)任何一門編程語言的具體語法之前比如怎么定義變量、怎么寫循環(huán)你首先得知道這門語言運(yùn)行在什么樣的“星球”上這個(gè)星球有哪些“大陸”和“海洋”以及你手里的工具編譯器是如何在這片土地上建造出可運(yùn)行的程序應(yīng)用程序的。C#就是這個(gè)星球上的一種“語言”而.NET框架就是承載這片語言的“生態(tài)系統(tǒng)”和“運(yùn)行環(huán)境”。我剛開始學(xué)C#的時(shí)候也曾跳過這些“枯燥”的背景知識(shí)直接去啃變量、類、繼承。結(jié)果就是當(dāng)遇到“為什么我需要引用這個(gè)System命名空間”、“.dll文件到底是什么”、“CLR又是什么鬼”這些問題時(shí)完全是一頭霧水調(diào)試起來事倍功半。所以花點(diǎn)時(shí)間理解C#和.NET的關(guān)系絕不是浪費(fèi)時(shí)間而是為你后續(xù)的高效學(xué)習(xí)和排錯(cuò)打下堅(jiān)實(shí)的地基。C#是一門現(xiàn)代的、面向?qū)ο蟮?、類型安全的編程語言。它由微軟在2000年左右推出設(shè)計(jì)初衷就是為了更好地構(gòu)建在.NET框架上運(yùn)行的各種應(yīng)用程序。你可以把它想象成一種非常精良的“建筑設(shè)計(jì)語言”。而.NET框架如今更準(zhǔn)確的稱呼是.NET平臺(tái)或.NET生態(tài)系統(tǒng)則是一個(gè)龐大的“建筑工地”和“預(yù)制件倉庫”。這個(gè)工地提供了一套統(tǒng)一的規(guī)范.NET標(biāo)準(zhǔn)、一個(gè)強(qiáng)大的運(yùn)行時(shí)引擎CLR、以及一個(gè)海量的、現(xiàn)成的功能庫.NET類庫。你用C#這套語言畫出的設(shè)計(jì)圖源代碼經(jīng)過特定的工具編譯器翻譯最終能在.NET這個(gè)工地上被建造和運(yùn)行起來?,F(xiàn)在熱門的.NET Core、.NET 5/6/7/8乃至最新的.NET 9都是這個(gè).NET生態(tài)系統(tǒng)在新時(shí)代的演進(jìn)它們跨平臺(tái)Windows, Linux, macOS、開源、高性能是當(dāng)前開發(fā)的主流選擇。而傳統(tǒng)的.NET Framework則是Windows平臺(tái)上的經(jīng)典版本。第一章通常會(huì)從歷史沿革講起幫你理清這些“.NET”們之間的關(guān)系讓你知道你現(xiàn)在學(xué)的東西既能用在哪兒又該如何選擇起點(diǎn)。2. .NET生態(tài)系統(tǒng)的核心架構(gòu)解析當(dāng)我們說“.NET”時(shí)它指的并不是一個(gè)單一的軟件而是一個(gè)層次分明的技術(shù)棧。理解這個(gè)架構(gòu)就像理解一臺(tái)電腦有硬件、操作系統(tǒng)和應(yīng)用軟件一樣重要。下面我們來層層拆解。2.1 公共語言運(yùn)行時(shí)程序的“操作系統(tǒng)”公共語言運(yùn)行時(shí)簡(jiǎn)稱CLR是.NET的心臟。它是所有.NET程序無論用什么語言編寫C#、VB.NET、F#等最終運(yùn)行的環(huán)境。你可以把它類比為Java的JVMJava虛擬機(jī)或者一個(gè)高度智能的“托管環(huán)境”。CLR的核心工作包括內(nèi)存管理垃圾回收GC這是CLR最著名的特性之一。在C里你需要手動(dòng)new和delete來分配和釋放內(nèi)存稍有不慎就會(huì)導(dǎo)致內(nèi)存泄漏或野指針。在.NET中CLR的垃圾回收器會(huì)自動(dòng)跟蹤對(duì)象的使用情況在對(duì)象不再被引用時(shí)自動(dòng)回收其內(nèi)存。這極大地減輕了開發(fā)者的負(fù)擔(dān)避免了大量?jī)?nèi)存管理錯(cuò)誤。即時(shí)編譯與執(zhí)行你的C#源代碼首先被編譯成一種叫做“中間語言”的代碼。當(dāng)程序運(yùn)行時(shí)CLR的即時(shí)編譯器會(huì)將IL代碼針對(duì)當(dāng)前運(yùn)行的CPU架構(gòu)進(jìn)行優(yōu)化編譯成本地機(jī)器碼執(zhí)行。這個(gè)過程兼顧了跨平臺(tái)性IL是平臺(tái)無關(guān)的和運(yùn)行效率最終是本地代碼。異常處理.NET提供了一套結(jié)構(gòu)化的、跨語言的統(tǒng)一異常處理機(jī)制。try-catch-finally這套語法就是由CLR在底層提供支持的。代碼訪問安全CLR可以驗(yàn)證IL代碼的類型安全和行為防止惡意代碼執(zhí)行非法操作在現(xiàn)代.NET中此功能的重要性已有所變化但架構(gòu)基礎(chǔ)仍在。注意很多新手會(huì)混淆“編譯”的概念。在.NET中編譯其實(shí)分兩步第一步是C#編譯器將.cs文件編譯成包含IL代碼的.dll或.exe稱為程序集第二步是程序運(yùn)行時(shí)CLR的JIT編譯器將IL編譯為本地代碼。所以你發(fā)布的程序包里包含的是IL不是直接的機(jī)器碼。2.2 基礎(chǔ)類庫觸手可及的“萬能工具箱”如果說CLR是發(fā)動(dòng)機(jī)那么.NET的基礎(chǔ)類庫就是裝滿各種精密工具的超級(jí)工具箱。BCL是一個(gè)龐大的、面向?qū)ο蟮?、可重用的類型集合封裝了無數(shù)常用的功能。這些類庫被組織在System及其子命名空間下例如System.IO用于文件讀寫、目錄操作。System.Net用于網(wǎng)絡(luò)通信如HTTP請(qǐng)求。System.Data用于數(shù)據(jù)庫訪問ADO.NET。System.Collections.Generic提供了泛型集合如ListT,DictionaryTKey, TValue比傳統(tǒng)的ArrayList更安全高效。System.Linq提供語言集成查詢功能讓你能用類似SQL的語法操作集合。System.Text包含用于字符串處理和編碼的類如StringBuilder。實(shí)操心得學(xué)習(xí)C#很大一部分就是在學(xué)習(xí)如何熟練使用BCL。不要試圖自己從頭實(shí)現(xiàn)一個(gè)復(fù)雜的文件解析器或網(wǎng)絡(luò)客戶端先去BCL里找找99%的概率已經(jīng)有現(xiàn)成的、經(jīng)過千錘百煉的類等著你調(diào)用。掌握利用文檔如Microsoft Docs快速查找所需類和方法的能力比死記硬背所有API重要得多。2.3 程序集與中間語言.NET的“交付物”與“通用語”程序集這是.NET中部署和版本控制的基本單元。它通常是一個(gè).exe可執(zhí)行文件或.dll動(dòng)態(tài)鏈接庫文件。但請(qǐng)注意這個(gè).dll/.exe內(nèi)部包含的不是傳統(tǒng)的Windows本地代碼而是IL代碼和元數(shù)據(jù)。元數(shù)據(jù)描述了程序集內(nèi)的所有類型、方法、屬性等信息使得程序集是“自描述”的這為反射、智能提示等高級(jí)特性提供了基礎(chǔ)。中間語言IL是一種介于高級(jí)語言如C#和機(jī)器碼之間的、面向堆棧的指令集。所有.NET語言最終都編譯為IL這是實(shí)現(xiàn).NET跨語言互操作性的關(guān)鍵。例如用C#寫的類庫可以直接被VB.NET項(xiàng)目引用和使用。為了更直觀地理解從C#源代碼到最終運(yùn)行的整個(gè)過程以及各組件的關(guān)系可以參考下面的簡(jiǎn)化流程圖flowchart TD A[C# 源代碼br.cs 文件] -- B[C# 編譯器brcsc.exe / Roslyn] B -- C[程序集br.exe 或 .dll 文件br內(nèi)含 IL 代碼與元數(shù)據(jù)] C -- D{程序啟動(dòng)} D -- E[公共語言運(yùn)行時(shí) CLR] E -- F[類加載器] F -- G[即時(shí)編譯器 JIT] G -- H[優(yōu)化后的本地機(jī)器碼] H -- I[CPU 執(zhí)行] J[.NET 基礎(chǔ)類庫 BCL] -.- B J -.- E subgraph K [.NET 框架/平臺(tái)] E J end style A fill:#e1f5fe style C fill:#f3e5f5 style H fill:#e8f5e8 style K fill:#fff3e0這個(gè)流程展示了“編譯時(shí)”和“運(yùn)行時(shí)”兩個(gè)關(guān)鍵階段。你的代碼和龐大的BCL在編譯時(shí)被組織在一起最終在CLR這個(gè)統(tǒng)一的“托管環(huán)境”中高效、安全地運(yùn)行。3. C#語言的核心特性與設(shè)計(jì)哲學(xué)了解了運(yùn)行環(huán)境我們?cè)賮砜纯碈#這門語言本身。它之所以能成為.NET平臺(tái)的首選語言并持續(xù)流行源于其一系列優(yōu)秀的設(shè)計(jì)特性和持續(xù)不斷的現(xiàn)代化演進(jìn)。3.1 面向?qū)ο缶幊痰娜嬷С諧#從誕生起就是一門純粹的面向?qū)ο笳Z言盡管后來加入了更多范式。這意味著幾乎所有東西都是對(duì)象object都繼承自一個(gè)共同的根System.Object。類與對(duì)象這是OOP的基石。類是藍(lán)圖對(duì)象是根據(jù)藍(lán)圖創(chuàng)建的實(shí)例。封裝通過public、private、protected、internal等訪問修飾符來控制對(duì)類成員字段、屬性、方法的訪問隱藏內(nèi)部實(shí)現(xiàn)細(xì)節(jié)只暴露必要的接口。繼承允許一個(gè)類派生類繼承另一個(gè)類基類的成員實(shí)現(xiàn)代碼復(fù)用和層次化設(shè)計(jì)。C#只支持單根繼承一個(gè)類只能有一個(gè)直接基類但可以通過接口實(shí)現(xiàn)多繼承的效果。多態(tài)允許將派生類對(duì)象當(dāng)作基類對(duì)象來處理并通過虛方法、抽象方法、接口實(shí)現(xiàn)“同一操作作用于不同對(duì)象產(chǎn)生不同行為”的效果。避坑技巧慎用繼承優(yōu)先使用組合。不要為了復(fù)用一點(diǎn)點(diǎn)代碼就創(chuàng)建一個(gè)復(fù)雜的繼承鏈。過深的繼承層次會(huì)使代碼難以理解和維護(hù)。當(dāng)考慮“A是一個(gè)B”的關(guān)系成立且穩(wěn)定時(shí)才使用繼承否則考慮“A擁有B”的組合關(guān)系。3.2 類型安全與泛型類型安全是C#和CLR的核心優(yōu)勢(shì)之一。編譯器會(huì)在編譯時(shí)進(jìn)行嚴(yán)格的類型檢查防止許多常見的運(yùn)行時(shí)錯(cuò)誤比如將字符串誤當(dāng)作整數(shù)使用。泛型則將類型安全提升到了新的高度。在泛型出現(xiàn)之前我們使用ArrayList這樣的非泛型集合它內(nèi)部存儲(chǔ)的是object類型這意味著存入任何對(duì)象都需要裝箱取出時(shí)需要強(qiáng)制類型轉(zhuǎn)換既不安全可能引發(fā)InvalidCastException也影響性能。// 非泛型集合 - 不安全且低效 ArrayList oldList new ArrayList(); oldList.Add(10); // 裝箱發(fā)生值類型int被轉(zhuǎn)為object int num (int)oldList[0]; // 需要顯式拆箱和類型轉(zhuǎn)換 // 泛型集合 - 安全且高效 Listint newList new Listint(); newList.Add(10); // 無需裝箱類型為int int num newList[0]; // 無需轉(zhuǎn)換類型明確泛型允許你定義類型參數(shù)如ListT中的T在編譯時(shí)由具體的類型實(shí)參如int,string替換從而創(chuàng)建出類型安全的特定版本。這廣泛應(yīng)用于集合、委托、接口和方法中。3.3 現(xiàn)代語言特性的持續(xù)演進(jìn)C#語言團(tuán)隊(duì)保持著活躍的更新節(jié)奏幾乎每年都有新版本加入讓代碼更簡(jiǎn)潔、更富有表達(dá)力的特性。對(duì)于初學(xué)者了解這些特性的存在和方向很重要自動(dòng)屬性和屬性初始化器簡(jiǎn)化了屬性的定義。// C# 3.0之前 private string _name; public string Name { get { return _name; } set { _name value; } } // C# 3.0之后 public string Name { get; set; } 默認(rèn)名稱;Lambda表達(dá)式與LINQ讓處理集合和異步操作變得聲明式、函數(shù)式。var evenNumbers numbers.Where(n n % 2 0).OrderBy(n n);異步編程async和await關(guān)鍵字讓編寫異步代碼像寫同步代碼一樣簡(jiǎn)單避免了回調(diào)地獄是現(xiàn)代Web、UI和IO密集型應(yīng)用的標(biāo)配。模式匹配從C# 7.0開始引入并不斷增強(qiáng)提供了更強(qiáng)大的條件分支和數(shù)據(jù)解構(gòu)能力。記錄類型C# 9.0引入用于創(chuàng)建不可變的、主要用于存儲(chǔ)數(shù)據(jù)的類型自動(dòng)實(shí)現(xiàn)值相等性比較非常簡(jiǎn)潔。public record Person(string FirstName, string LastName);學(xué)習(xí)建議對(duì)于初學(xué)者不必一開始就追求掌握所有最新特性。牢牢掌握C#的基礎(chǔ)語法變量、流程控制、類、接口、委托、事件、OOP核心思想和泛型。在有了扎實(shí)基礎(chǔ)后再逐步將async/await、LINQ、模式匹配等現(xiàn)代特性融入到你的編程實(shí)踐中你會(huì)深刻體會(huì)到它們帶來的效率提升。4. 開發(fā)環(huán)境搭建與第一個(gè)程序理論說得再多不如動(dòng)手一試。搭建開發(fā)環(huán)境是第一步。4.1 開發(fā)工具的選擇與安裝Visual Studio這是微軟官方的集成開發(fā)環(huán)境功能極其強(qiáng)大社區(qū)版免費(fèi)。它集成了代碼編輯器、調(diào)試器、圖形化設(shè)計(jì)器、NuGet包管理器、Git工具等幾乎所有你需要的東西。對(duì)于Windows平臺(tái)的開發(fā)者它是首選。安裝時(shí)選擇“.NET桌面開發(fā)”或“ASP.NET和Web開發(fā)”等工作負(fù)載它會(huì)自動(dòng)安裝對(duì)應(yīng)版本的.NET SDK。Visual Studio Code這是一個(gè)輕量級(jí)但功能強(qiáng)大的跨平臺(tái)源代碼編輯器。通過安裝C#擴(kuò)展包它可以獲得優(yōu)秀的智能提示、調(diào)試和項(xiàng)目管理功能。對(duì)于喜歡輕量級(jí)、跨平臺(tái)macOS, Linux或前端全棧的開發(fā)者VS Code是絕佳選擇。.NET SDK無論你選擇哪個(gè)編輯器都必須安裝.NET SDK。它包含了編譯和運(yùn)行.NET程序所需的編譯器、庫和運(yùn)行時(shí)。你可以從微軟官網(wǎng)下載并安裝最新穩(wěn)定版。實(shí)操步驟以VS Code為例訪問 code.visualstudio.com 下載并安裝VS Code。打開VS Code進(jìn)入擴(kuò)展市場(chǎng)搜索并安裝“C#”擴(kuò)展由Microsoft發(fā)布。訪問 dotnet.microsoft.com 下載并安裝.NET SDK。打開終端VS Code中按Ctrl輸入dotnet --version驗(yàn)證安裝成功。4.2 創(chuàng)建、運(yùn)行與理解第一個(gè)控制臺(tái)應(yīng)用讓我們用命令行來感受最純粹的過程這能幫你理解背后的機(jī)制。創(chuàng)建項(xiàng)目打開終端導(dǎo)航到你希望存放代碼的目錄執(zhí)行以下命令dotnet new console -n HelloDotNet cd HelloDotNet這條命令使用dotnet new模板創(chuàng)建了一個(gè)名為HelloDotNet的控制臺(tái)應(yīng)用程序項(xiàng)目。你會(huì)看到生成了一個(gè)HelloDotNet.csproj項(xiàng)目文件和一個(gè)Program.cs源代碼文件。解讀項(xiàng)目文件打開HelloDotNet.csproj它可能看起來像這樣Project SdkMicrosoft.NET.Sdk PropertyGroup OutputTypeExe/OutputType TargetFrameworknet8.0/TargetFramework ImplicitUsingsenable/ImplicitUsings Nullableenable/Nullable /PropertyGroup /ProjectTargetFramework指定了項(xiàng)目目標(biāo)框架這里是.NET 8.0。ImplicitUsings啟用隱式全局using指令自動(dòng)為常見命名空間如System添加引用。Nullable啟用可空引用類型上下文這是一項(xiàng)重要的類型安全增強(qiáng)特性。解讀與修改代碼打開Program.cs你會(huì)看到類似以下代碼// See https://aka.ms/new-console-template for more information Console.WriteLine(Hello, World!);這就是C# 9.0及以后為頂級(jí)語句提供的簡(jiǎn)化模板。它省略了傳統(tǒng)的namespace、class Program和static void Main方法定義讓你可以直接編寫執(zhí)行代碼。這對(duì)于小程序和學(xué)習(xí)來說非常簡(jiǎn)潔。你可以修改字符串內(nèi)容。運(yùn)行程序在終端中確保位于項(xiàng)目目錄下執(zhí)行dotnet run你會(huì)看到輸出“Hello, World!”。dotnet run命令依次執(zhí)行了dotnet restore還原依賴、dotnet build編譯和dotnet assembly運(yùn)行的操作。深入一步查看生成文件運(yùn)行后在項(xiàng)目目錄下會(huì)生成bin和obj文件夾。bin/Debug/net8.0目錄下就存放著編譯輸出的程序集HelloDotNet.dll或HelloDotNet.exe取決于平臺(tái)。你可以嘗試直接運(yùn)行它在Windows上雙擊.exe或在命令行用dotnet HelloDotNet.dll運(yùn)行感受一下“交付物”是什么。常見問題與排查錯(cuò)誤找不到命令dotnet說明.NET SDK未正確安裝或環(huán)境變量PATH未配置。請(qǐng)重新安裝SDK或手動(dòng)將SDK安裝路徑如C:\Program Files\dotnet添加到系統(tǒng)環(huán)境變量PATH中。錯(cuò)誤項(xiàng)目文件不兼容可能是項(xiàng)目文件格式舊或當(dāng)前SDK版本不支持目標(biāo)框架。嘗試用dotnet new重新創(chuàng)建項(xiàng)目或檢查并更新.csproj文件中的TargetFramework為已安裝的SDK支持的版本如net8.0。VS Code中C#擴(kuò)展沒有智能提示確保已打開包含.csproj文件的項(xiàng)目根目錄文件夾。有時(shí)需要等待擴(kuò)展初始化完成或按CtrlShiftP輸入“OmniSharp: Restart OmniSharp”來重啟語言服務(wù)器。5. 跨越新手期核心概念深度辨析與避坑指南掌握了基本操作后一些核心概念的深入理解能幫你避開許多坑。5.1 值類型與引用類型理解數(shù)據(jù)存儲(chǔ)的本質(zhì)這是C#類型系統(tǒng)中最基礎(chǔ)、最重要的區(qū)分直接關(guān)系到性能、內(nèi)存和行為。特性值類型引用類型存儲(chǔ)位置通常存儲(chǔ)在棧上作為局部變量時(shí)或內(nèi)聯(lián)在引用類型對(duì)象中。對(duì)象本身存儲(chǔ)在托管堆上變量存儲(chǔ)的是對(duì)象的引用地址。賦值行為復(fù)制整個(gè)值。將一個(gè)值類型變量賦值給另一個(gè)會(huì)創(chuàng)建一份完整的副本。復(fù)制引用。將一個(gè)引用類型變量賦值給另一個(gè)兩者指向堆上的同一個(gè)對(duì)象。默認(rèn)值各字段被設(shè)置為該類型的默認(rèn)值如int為0bool為false。默認(rèn)值為null表示不引用任何對(duì)象。繼承隱式密封不能作為其他類型的基類但可以實(shí)現(xiàn)接口。所有值類型都繼承自System.ValueType??梢岳^承其他類也可以被繼承。示例int,double,bool,char,struct結(jié)構(gòu)體,enum枚舉class類,interface接口,delegate委托,array數(shù)組,string關(guān)鍵影響與避坑性能對(duì)于小型、不可變的數(shù)據(jù)值類型特別是struct通常有更好的局部性和更少的堆內(nèi)存分配/垃圾回收壓力。但大型值類型在作為方法參數(shù)傳遞時(shí)默認(rèn)按值傳遞會(huì)產(chǎn)生復(fù)制開銷??罩抵殿愋妥兞坎荒転閚ull除非使用可空類型int?。引用類型變量可以為null在訪問其成員前必須進(jìn)行空值檢查否則會(huì)拋出NullReferenceException這是最常見的運(yùn)行時(shí)錯(cuò)誤之一。相等性比較值類型比較通常是比較兩個(gè)值的所有字段是否相等。引用類型默認(rèn)的操作符比較的是引用是否相等是否指向同一對(duì)象若要比較內(nèi)容是否相等需要重寫Equals和GetHashCode方法或使用Equals方法。5.2 命名空間與程序集組織代碼的兩種維度新手常?;煜@兩個(gè)概念。命名空間這是一種邏輯上的組織方式用于避免類型名稱沖突并讓代碼結(jié)構(gòu)更清晰。例如System.IO命名空間下包含文件IO相關(guān)的類System.Data.SqlClient包含SQL Server客戶端相關(guān)的類。使用using指令來引入命名空間簡(jiǎn)化類型名稱。程序集這是一個(gè)物理上的部署單元是一個(gè).dll或.exe文件。一個(gè)程序集可以包含多個(gè)命名空間下的類型一個(gè)命名空間下的類型也可以分布在多個(gè)程序集中。關(guān)系你通過“添加引用”將一個(gè)程序集物理文件引入到你的項(xiàng)目中。然后在你的代碼中通過using指令來使用該程序集中特定命名空間下的類型邏輯組織。5.3 垃圾回收機(jī)制淺析與最佳實(shí)踐CLR的垃圾回收是自動(dòng)的但了解其基本工作原理有助于你編寫更高效、更少內(nèi)存問題的代碼。GC主要回收的是托管堆上不再被任何“根”引用的對(duì)象。根包括靜態(tài)字段、局部變量、CPU寄存器等。給開發(fā)者的建議最佳實(shí)踐讓短命對(duì)象盡快死亡GC對(duì)第0代最新創(chuàng)建的對(duì)象的回收最快。盡量讓臨時(shí)對(duì)象在方法執(zhí)行完畢后立即不可達(dá)。避免不必要的對(duì)象創(chuàng)建特別是在循環(huán)或頻繁調(diào)用的方法中??紤]重用對(duì)象使用對(duì)象池、使用值類型如果合適、或使用StringBuilder代替頻繁的字符串拼接。及時(shí)釋放非托管資源對(duì)于文件句柄、數(shù)據(jù)庫連接、網(wǎng)絡(luò)套接字等非托管資源GC不知道如何釋放它們。必須實(shí)現(xiàn)IDisposable接口并在using語句中或手動(dòng)調(diào)用Dispose()方法來確保資源被及時(shí)釋放。using (var fileStream new FileStream(test.txt, FileMode.Open)) { // 使用fileStream } // 離開using塊時(shí)Dispose()會(huì)自動(dòng)被調(diào)用即使發(fā)生異常也會(huì)。謹(jǐn)慎使用靜態(tài)成員和事件靜態(tài)字段引用的對(duì)象會(huì)一直存活直到AppDomain卸載可能導(dǎo)致內(nèi)存泄漏。事件訂閱如果不取消也會(huì)阻止訂閱者對(duì)象被回收。不要手動(dòng)調(diào)用GC.Collect()GC的算法是高度優(yōu)化的手動(dòng)強(qiáng)制回收通常會(huì)打亂其節(jié)奏降低性能。只在有非常明確和特殊的性能分析依據(jù)時(shí)才考慮使用。理解C#與.NET框架的關(guān)系是編寫高效、健壯.NET應(yīng)用程序的起點(diǎn)。它不僅僅是學(xué)習(xí)語法更是理解整個(gè)平臺(tái)的運(yùn)行哲學(xué)。從CLR的托管環(huán)境到BCL的豐富類庫從值類型與引用類型的本質(zhì)區(qū)別到現(xiàn)代語言特性的靈活運(yùn)用每一步都環(huán)環(huán)相扣。