手動移除 <PackageReference> 後,為什麼還要執行 dotnet restore?

| .NET | 4 Reads

在 .NET 開發中,我們常透過 NuGet 套件來引入外部功能模組。這些套件的引用是透過 .csproj 中的 <PackageReference> 來控制的。然而,當你手動編輯 .csproj、移除某些套件時,是否就已經完成了「卸載」?

答案是:還沒完全。

本文將說明為什麼你在手動移除 <PackageReference> 後,還需要額外執行 dotnet restore,才能讓你的專案環境真正乾淨。


🧱 一般的 NuGet 套件管理流程

在 Visual Studio 或 CLI 中,NuGet 的套件管理流程大致如下:

  1. <PackageReference> 加入 .csproj

  2. 執行 dotnet restore → 從 NuGet 快取/網路下載對應套件

  3. 編譯器使用還原後的 .dll 作為參考

當你透過 Visual Studio 的「NuGet 套件管理器」卸載套件時,它會:

  • .csproj 移除 <PackageReference>

  • 自動執行 dotnet restore

  • .obj/.bin/ 中過時的 DLL 被移除,確保乾淨


🛠️ 問題來了:你手動刪掉 <PackageReference> 後會發生什麼?

你可能在某次 commit 或 merge 時手動刪除了:

<PackageReference Include="System.Management" Version="9.0.2" />

但是這樣操作後,如果不執行 dotnet restore 或重新編譯專案,以下問題就可能出現:

🚫 舊 DLL 還在被引用

即使 <PackageReference> 被移除,obj/ 目錄下的中間產物(包括 DLL)仍然存在,可能仍會:

  • 被編譯器誤用(尤其是增量編譯或未 rebuild 的情況下)

  • 導致你誤以為該套件仍可使用

🔍 IDE 無法即時反映變化

Visual Studio 在某些情況下不會即時重新還原,除非你主動 rebuild 或重新開啟專案。這會讓 IntelliSense 停留在錯誤狀態,或出現模稜兩可的提示。


✅ 解法:手動刪除後,請至少執行一次:

dotnet restore

或更乾淨的做法:

dotnet clean
dotnet build

這樣會:

  • 更新專案依賴狀態

  • 移除無效 DLL 與過時的中繼資料

  • 確保你專案環境與 .csproj 完全一致


🧪 示範案例

假設你原本的 .csproj 包含:

<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="9.0.2" />

你手動將它刪除後,沒做任何事,卻發現:

using System.Diagnostics;

仍然可以編譯?這可能是因為 之前還原的 DLL 還殘留在 obj/

這正是為什麼你不能只刪 <PackageReference> 就算完成卸載


✍️ 小結

操作 是否足夠? 建議補充動作
只刪除 <PackageReference> ❌ 不夠 dotnet restorebuild
使用 NuGet GUI 卸載 ✅ 足夠 自動會還原
清掉快取套件(非必要) ❌ 不必做 除非要省空間或清理干擾

🔚 結語

手動移除 <PackageReference> 後,記得執行 dotnet restorebuild,才能讓你的環境真正反映最新的專案狀態。

別讓看似簡單的移除,留下不易察覺的殘影!

This article was last edited at