.NET Framework 相容性簡介

前言

從 .NET 框架 4.0 開始,所有主版本號為 4(稱為 “4.x” 版本)的 .NET 框架,都會進行就地更新。這就意味著在一段時間內,電腦上安裝的只有一個 .NET 4.x 框架。安裝 .NET 4.5 框架將替換 .NET 4.0 框架,.NET 4.5.1 框架將替換 .NET 4.5 框架,.NET 4.6 框架將替換 .NET 4.5.1,以此類推。

由於這些就地更新的特點,原本在 .NET 4.0 框架上運行的應用程式,在電腦安裝的 .NET 框架升級後,可能需要在 .NET 4.6 上運行。.NET 4.x 框架之間的相容性是非常高的,因此在 .NET 4.x 框架下正常工作的應用程式,通常也會在較新版本的 .NET 框架下正常運行。然而不同的 .NET 4.x 框架會有一些變化,因此應用程式應該在其將運行的任何版本的 .NET 框架上測試下。

本文概述了最佳做法和工具,用來使支持新的 .NET 版本更容易。

 

發生了哪些變化?為什麼?

對於 .NET 團隊來說,和之前版本的 .NET 框架的相容性,是一個高優先順序的工作。事實上,.NET 框架所有的更改都是由經驗豐富的工程師進行審核,他們會對這些改變在客戶的應用程式上的影響進行評估。

儘管如此,仍然存在相容性問題。原因之一是,在更新 .NET 框架時,相容性並不是唯一的優先事項。有時,由於功能性的原因,不得不進行更改,來解決某個安全性漏洞,或者是支持某個行業標準。

還有一些偶然發生的相容性問題。.NET 框架團隊會進行全面的相容性測試,以防止這些問題,但仍然會漏掉一些問題。還有更複雜的情況,修復相容性問題本身就是一種影響相容性的改變(因為有些用戶可能依賴於這些無意的新行為)。在這樣的情況下(解決無意的行為更改),.NET 框架團隊常常會使用一個稱為 “Quirking” 的解決方案。

 

Quirking 和目標 .NET 框架

Quirking 指的是對於緩解相容性問題,在 .NET 框架中有兩個單獨的程式碼路徑,並且選擇一種作為應用程式的目標 .NET 框架版本的路徑。這種方式緩解了許多 .NET 框架相容性的問題,因為應用程式在較新的 .NET 框架上運行時,只要在沒有變化的目標 .NET 框架中運行,就避免了很多潛在的問題。Quirking 行為是被應用程式的目標 .NET 框架自動確定,但可以由開發人員使用應用程式或電腦配置設置來進行重寫。雖然減輕了很多相容性的問題,但是由於安全方面的考慮,以及技術上的限制,並不是所有的相容性問題都可以被 Quirking 行為解決。

舉一個例子,如果一個目標 .NET 框架是 4.5 的應用程式,在安裝了 .NET 4.5.2 的電腦上運行,即使在較新的框架上執行應用程式,為了減少相容性問題,它也會模擬 .NET 4.5 的行為。

目前, 微軟對  .NET 4.0 ,4.5 和 4.5.1 已停止支援 但是需要特別注意的是 根據新  .NET 框架的支援政策  以那些低版本為目標  .NET 框架的應用程式在高版本的  .NET 框架上的正常運行,將會繼續得到支援。

目標版本是在創建應用程式定義域(通常是在託管可執行檔啟動時)時,由應用程式的主程序集的目標框架屬性決定的。此屬性可以通過以下方式設置︰

Quirking 設置是應用程式定義域範圍。在大多數情況下,類庫(dll 的)將根據依賴於它們的可執行檔,而使用或者不使用 Quirking。正因為如此,即使沒有 Quirking 應用,創建者的共用庫可能需要確保他們的程式碼能夠正常工作。

 

相容性開關

除了基於 .NET 目標框架的自動急轉之外,開發人員可以通過設置相容性開關,明確選擇使用或者不使用影響相容性的變化,手動啟用或禁用個別相容性急轉(以及其他一些不是自動急轉的行為)。這些“相容性開關”對於允許開發人員把較新版本的 .NET 框架作為目標 .NET 框架(為了使用 .NET 的新功能)時非常有用,這樣仍然可以選擇不使用一些已知的會影響應用程式的改動。相容性開關設置方式有以下幾種:

  • 通過設定檔設置
  • 通過環境變數設置
  • 在專案的原始程式碼中以程式設計方式設置

如何設置相容性開關的詳細資訊,雖然沒有在這篇文章中提到,但在後續會有關於這方面更多深入的細節。

在 MSDN 上關於相容性問題的文件中,經常會提到相容性開關,需要時可以查閱。

 

相容性問題文件

所有已知的 .NET 框架相容性問題都記錄在 MSDN 上。

從 .NET 框架 4.5.1 開始,相容性問題被列為“運行時更改” 或 “重定向更改”。

  • 運行時更改,指的是影響任意應用程式在較新的 .NET 框架版本(這些變化不是 Quirking)上運行的更改。
  • 重定向更改,指的是只影響應用程式重新以較新 .NET 框架為目標框架生成的更改。這些是 .NET 框架變化,或者是編譯工具的變化。對於 .NET 4.0 和 .NET 4.5 之間的變化,在相容性問題表的專案裡,運行時和重定向的區別並不顯示,但可以通過閱讀說明來進行區分。

除了 MSDN 上面的文件,.NET 框架相容性問題都可以作為標記文件 ,是可供使用的相容性工具(見下文)。可以通過直接讀取參考文件 (或在列表的 MSDN 中), 來瞭解有關相容性的問題。這個參考檔是開源 GitHub 存儲庫中的一部分,可以提交請求,或者創建任何需要修正的問題。.NET 團隊會將參考檔上面的資訊和 MSDN 上的資訊進行同步。

 

編譯器的相容性問題

除了上文提到的 .NET 框架運行時和重定向的相容性問題之外,在不能進行急轉的 C# 和 VB 編輯器版本之間,還有一小部分不會發生在運行時的更改問題。例如,由於 C# 4.0 編譯器和 5.0 C# 編譯器 在生成中間語言時的極小差異,開發人員在新的編輯器中重新編譯應用程式的時候,必須留意此類問題。

因為這些相容性問題僅在新的編譯器中重新編譯時才會顯現,所以它們不會影響到以前編譯過的二進位檔案在新版本的 .NET 框架上運行。為此,MSDN 文件中將這些問題歸類為重定向的變化。相容性問題標記文件會將編譯器相容性問題標記為“編譯時”的重定向的更改問題,這種問題和 “Quirking “ 重定目標更改有一些差異。

 

問題識別工具

在 GitHub 上發佈相容性問題標記檔的主要目的,是為了相容性工具的使用。這些工具使得從一個 .NET 框架版本到另一個的遷移變得比較容易。現在,我們介紹以下兩個相容性分析工具集。

API 移植性分析器

ApiPort(該工具的簡稱),它能夠掃描二進位檔案,並標識應用程式介面(以下簡稱 API)使用的所有 .NET 框架。然後,它將這些 API 和相容性問題參考文件中存儲的資料進行比較,並針對所使用的 API 提供一份報告,是關於一個 .NET 框架 4.x 和另一個版本之間的 API 的一些更改。命令列選項可以縮小掃描範圍 (例如,只考慮指定的 .NET 框架版本之間的更改)。完整文件請參閱 ApiPort 中斷更改掃描使用說明。使用 ApiPort 工具時,需要牢記的注意事項有以下兩點:

  1. 因為 ApiPort 只關注 API 調用的 .NET,因此它有可能會發一些誤報。大多數 .NET 相容性問題只影響某個 API 的特定程式碼路徑。簡單地使用這些 API,並不意味著應用程式就會受到相容性問題的影響。詳讀更改說明,以確定所報告的問題是否有可能在你的特定應用程式中出現。
  2. 因為 ApiPort 只關注 API 調用的 .NET,一些相容性問題無法通過此工檢測出來。例如,當只掃描中間語言時,在 WPF 應用程式中使用已更改的 XAML 控制項可能不會被發現。 ApiPort 是一個很有用的工具,但不能替代相容性測試的。

.NET 框架相容性分析器

.NET 框架相容性分析器是一整套 Roslyn 診斷程式碼分析器,其使用原始程式碼中的語法樹以及語義模型,從而更智慧地決定一個專案是否會遇到相容性問題。他們仍然會存在誤報,但相比 ApiPort 工具會準確很多。

這些工具可以透過在 NuGet.org 網頁上搜尋 Microsoft.DotNet.FrameworkCompatibilityDiagnostics 得到。.NET 框架團隊目前正在對這些分析器開放原始碼。想要獲得更多的在開放原始程式碼成果的更新,請關注這個網頁。

 

報告新的相容性問題

當把應用程式從一個 .NET 框架版本遷移到另一個的時候,你偶爾可能會遇到在 MSDN 或 ApiPort 參考文件中沒有記錄的相容性問題。如果這種情況發生,請讓我們知道!.NET 團隊將會不斷地保持相容性文件是最新的。

在 .NET 框架中,沒有文件說明的相容性問題可以用以下方式報告:

  • 使用 Visual Studio 裡面的 ”發送笑臉” 回饋功能來發送詳細的變更。
  • 在 ApiPort 存儲庫中創建問題來題記錄那些還沒有被記錄在工具的標記文件中的 .NET 框架相容性問題。.NET 的團隊(或社群成員)將會調查並適當的添加文件和支援。

 

結語

.NET 框架力求與每個新的框架版本高度相容。儘管如此,一些相容性問題仍然是不可避免的。瞭解這些變化,並且知道怎樣去緩解這些問題,可以保持你的應用程式在新版本的 .NET 框架上成功運行。

本文提及的一些相容性最佳做法包括:

  • 不是必須的情況,不要重定向為較新版本的 .NET 框架來作為目標框架。因為這樣應用程式可以利用相容性 ”Quirking” 功能,從而使相容性問題減少到最低限度。
  • 如果你在用來運行你的應用程式的 .NET 框架版本上有任何的控制項,就使用較新版本的 .NET 框架。這是因為 .NET4.x 上面的許多相容性問題已經在後續版本中得到了修復。例如,在 4.0 至 4.6 之間的相容性問題就比 4.0 到 4.5 之間的相容性問題少。
  • 如果應用程式是使用較新的編譯器重新編譯的,就一定要確保進行徹底的測試。這可以找出編譯器相容性問題 (雖然這些問題很少見)。
  • 使用相容性工具找出潛在問題,常用的工具有 API 移植性分析器 和 .NET 框架相容性分析器
  • 在你期望運行的所有 .NET 框架版本上,測試你的應用程式。

使用這些技術,應用程式將會繼續在新版本的.NET 框架中運行。

 

相關資料

本篇翻譯自 Introduction to .NET Framework Compatibility