migrate-dotnet8-to-dotnet9 について
.NET 8 のプロジェクトやソリューションを .NET 9 に移行するためのエージェントスキルです。プロジェクトの技術領域に応じて互換性を確認し、ビルドや動作の問題、インフラ設定に対応します。
主な機能
- 01ビルド、テスト、技術領域の確認
- 02ターゲットフレームワークと Microsoft パッケージの更新
- 03プロジェクト種別に応じたコンパイル問題の解決
- 04.NET 9 の動作変更の確認
- 05コンテナーとデプロイ設定の更新
活用シーン
- 01net8.0 プロジェクトの net9.0 への更新
- 02SDK 更新後に発生したエラーや警告への対応
- 03ASP.NET Core 9 または EF Core 9 への適応
- 04.NET 9 向け Dockerfile とデプロイスクリプトの更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dotnet/ skills --skill migrate-dotnet8-to-dotnet9インストール後、Claude Code で/migrate-dotnet8-to-dotnet9を入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/aspnet-core-dotnet8to9.mdcontainers-interop-dotnet8to9.mdcore-libraries-dotnet8to9.mdcryptography-dotnet8to9.mdcsharp-compiler-dotnet8to9.mddeployment-runtime-dotnet8to9.mdefcore-dotnet8to9.mdsdk-msbuild-dotnet8to9.mdserialization-networking-dotnet8to9.mdwinforms-wpf-dotnet8to9.md詳細
.NET 8 → .NET 9 の移行
.NET 8 プロジェクトまたはソリューションを .NET 9 に移行し、すべての破壊的変更を体系的に解決します。最終的に、net9.0 をターゲットとするプロジェクトがクリーンにビルドされ、テストに合格し、.NET 9 リリースで導入された動作上、ソース互換性上、バイナリ互換性上のすべての変更に対応した状態になります。
使用する場面
TargetFrameworkをnet8.0からnet9.0にアップグレードする場合- .NET 9 SDK の更新後にビルドエラーや新しい警告を解決する場合
- .NET 9 ランタイム、ASP.NET Core 9、または EF Core 9 の動作変更に対応する場合
BinaryFormatterの使用箇所を置き換える場合(実行時に必ず例外がスローされるようになりました)- CI/CD パイプライン、Dockerfile、またはデプロイスクリプトを .NET 9 向けに更新する場合
使用しない場面
- プロジェクトがすでに
net9.0をターゲットとしており、クリーンにビルドされる場合 — 移行は完了しています。net10.0を目指す場合は、次のステップとしてmigrate-dotnet9-to-dotnet10スキルを使用してください。 - .NET 7 以前からアップグレードする場合 — まず以前のバージョンの破壊的変更に対応してください
- .NET Framework から移行する場合 — これは別個の、より大規模な作業です
- .NET 9 で新規に始めるプロジェクト — 移行は不要です
入力
| 入力 | 必須 | 説明 |
|---|---|---|
| プロジェクトまたはソリューションのパス | はい | 移行する .csproj、.sln、または .slnx のエントリポイント |
| ビルドコマンド | いいえ | ビルド方法(例:dotnet build、リポジトリのビルドスクリプト)。指定されていない場合は自動検出します |
| テストコマンド | いいえ | テストの実行方法(例:dotnet test)。指定されていない場合は自動検出します |
| プロジェクトの種類に関するヒント | いいえ | プロジェクトが ASP.NET Core、EF Core、WinForms、WPF、コンテナーなどを使用しているかどうか。指定されていない場合は、PackageReferences と SDK 属性から自動検出します |
ワークフロー
読み込まれた参照ドキュメントに基づいて直接回答してください。 破壊的変更に関する情報を得るために、ファイルシステムを検索したりウェブページを取得したりしないでください。参照ドキュメントに信頼できる詳細情報が記載されています。どの破壊的変更が該当するかを特定し、具体的な修正方法を提示してください。
コミット戦略: 論理的な区切りごとにコミットします。TFM の更新後(ステップ 2)、ビルドエラーの解決後(ステップ 3)、動作変更への対応後(ステップ 4)、インフラストラクチャの更新後(ステップ 5)にコミットしてください。これにより、各コミットの焦点が明確になり、レビューしやすくなります。
ステップ 1:プロジェクトを評価する
- プロジェクトのビルド方法とテスト方法を特定します。ビルドスクリプト、
.sln/.slnxファイル、または個別の.csprojファイルを確認してください。 dotnet --versionを実行し、.NET 9 SDK がインストールされていることを確認します。インストールされていない場合は、作業を中止してユーザーに知らせてください。- 次の項目を調べて、プロジェクトで使用されている技術領域を特定します。
- SDK 属性:
Microsoft.NET.Sdk.Web→ ASP.NET Core、<UseWPF>または<UseWindowsForms>を含むMicrosoft.NET.Sdk.WindowsDesktop→ WPF/WinForms - PackageReferences:
Microsoft.EntityFrameworkCore.*→ EF Core、Microsoft.Extensions.Http→ HttpClientFactory - Dockerfile の有無 → コンテナー関連の変更が該当
- P/Invoke またはネイティブ相互運用の使用 → 相互運用関連の変更が該当
BinaryFormatterの使用 → シリアル化の移行が必要System.Text.Jsonの使用 → シリアル化の変更が該当- X509Certificate のコンストラクター → 暗号化関連の変更が該当
- SDK 属性:
- 該当する参照ドキュメントを記録します(ステップ 3 の参照ドキュメント読み込み表を参照)。
- 現在の
net8.0ターゲットでクリーンビルド(dotnet build --no-incrementalを実行するか、bin/objを削除)を行い、クリーンなベースラインを確立します。既存の警告があれば記録してください。
ステップ 2:ターゲットフレームワークを更新する
-
各
.csproj(または一元管理している場合はDirectory.Build.props)で、次のように変更します。<TargetFramework>net8.0</TargetFramework>変更後:
<TargetFramework>net9.0</TargetFramework>マルチターゲットのプロジェクトでは、
<TargetFrameworks>にnet9.0を追加するか、net8.0を置き換えます。 -
すべての
Microsoft.Extensions.*、Microsoft.AspNetCore.*、Microsoft.EntityFrameworkCore.*およびその他の Microsoft パッケージ参照を 9.0.x バージョンに更新します。Central Package Management(Directory.Packages.props)を使用している場合は、そこでバージョンを更新します。 -
dotnet restoreを実行します。次の点に注意してください。- バージョン要件:.NET 9 SDK で
net9.0をターゲットにするには Visual Studio 17.12 以降が必要です(net8.0以前では 17.11)。 - .NET Standard 1.x と .NET 7 のターゲットに関する新しい警告:古いターゲットフレームワークの更新または削除を検討してください。
- バージョン要件:.NET 9 SDK で
-
クリーンビルドを実行します。すべてのエラーと新しい警告を収集してください。これらにはステップ 3 で対処します。
ステップ 3:ビルドエラーとソース互換性のない変更を解決する
コンパイルエラーと新しい警告に体系的に対処します。プロジェクトの種類に応じて、適切なリファレンスドキュメントを読み込みます。
| プロジェクトで使用しているもの… | 読み込むリファレンス |
|---|---|
| .NET 9 プロジェクト全般 | references/csharp-compiler-dotnet8to9.md |
| .NET 9 プロジェクト全般 | references/core-libraries-dotnet8to9.md |
| .NET 9 プロジェクト全般 | references/sdk-msbuild-dotnet8to9.md |
| ASP.NET Core | references/aspnet-core-dotnet8to9.md |
| Entity Framework Core | references/efcore-dotnet8to9.md |
| 暗号化 API | references/cryptography-dotnet8to9.md |
| System.Text.Json、HttpClient、ネットワーク機能 | references/serialization-networking-dotnet8to9.md |
| Windows Forms または WPF | references/winforms-wpf-dotnet8to9.md |
| Docker コンテナー、ネイティブ相互運用 | references/containers-interop-dotnet8to9.md |
| ランタイム構成、デプロイ | references/deployment-runtime-dotnet8to9.md |
ソース互換性に影響する、よくある変更を確認します:
-
paramsスパンのオーバーロード解決 —String.Join、String.Concat、Path.Combine、Task.WhenAllなどに新たに追加されたparams ReadOnlySpan<T>オーバーロードが、優先的に選択されるようになりました。これらのメソッドをExpressionラムダ内で呼び出すコードでは、エラー(CS8640/CS9226)が発生します。references/core-libraries-dotnet8to9.mdを参照してください。 -
StringValuesの曖昧なオーバーロード —params Span<T>機能により、String.Concat、String.Join、Path.CombineなどのメソッドでStringValuesの暗黙的な演算子との曖昧さが生じます。引数を明示的にキャストして修正します。references/core-libraries-dotnet8to9.mdを参照してください。 -
新しい廃止警告(SYSLIB0054–SYSLIB0057):
SYSLIB0054:Thread.VolatileRead/VolatileWriteをVolatile.Read/Volatile.Writeに置き換えますSYSLIB0057:X509Certificate2/X509Certificateのバイナリ/ファイル用コンストラクターをX509CertificateLoaderのメソッドに置き換えます- さらに、
SYSLIB0055(ARM AdvSimd の符号付きオーバーロード)およびSYSLIB0056(ハッシュアルゴリズムを指定した Assembly.LoadFrom)については、references/core-libraries-dotnet8to9.mdを参照してください
-
レコード構造体に対する C# 13 の
InlineArray—record struct型への[InlineArray]属性の指定が禁止されました(CS9259)。通常のstructに変更します。references/csharp-compiler-dotnet8to9.mdを参照してください。 -
C# 13 のイテレーターの安全コンテキスト — C# 13 では、イテレーター内に安全コンテキストが導入されるようになりました。外側の
unsafeクラスから unsafe コードを継承していたイテレーター内のローカル関数で、エラーが発生するようになります。ローカル関数にunsafe修飾子を追加します。references/csharp-compiler-dotnet8to9.mdを参照してください。 -
C# 13 のコレクション式のオーバーロード解決 — 空のコレクション式(
[])では、オーバーロードの優先順位を決める際に span と非 span の違いが使われなくなりました。要素型が完全に一致するものが優先されます。references/csharp-compiler-dotnet8to9.mdを参照してください。 -
String.Trim(params ReadOnlySpan<char>)の削除 —Trim/TrimStart/TrimEndにReadOnlySpan<char>を渡す .NET 9 プレビュー向けのコードは、再ビルドする必要があります。このオーバーロードは正式リリースで削除されました。references/core-libraries-dotnet8to9.mdを参照してください。 -
BinaryFormatterは常に例外をスローします — プロジェクトでBinaryFormatterを使用している場合は、作業を中断してユーザーに知らせてください。これは重要な判断を要します。references/serialization-networking-dotnet8to9.mdを参照してください。 -
HttpListenerRequest.UserAgentは null 許容です — このプロパティの型はstring?になりました。null チェックを追加します。references/serialization-networking-dotnet8to9.mdを参照してください。 -
Windows Forms の null 許容注釈の変更 — 一部の WinForms API パラメーターが、null 許容から null 非許容に変更されました。呼び出し箇所を更新します。
references/winforms-wpf-dotnet8to9.mdを参照してください。 -
Windows Forms のセキュリティアナライザー(WFO1000) — シリアル化の設定を明示していないプロパティに対し、新しいアナライザーがエラーを出力します。
references/winforms-wpf-dotnet8to9.mdを参照してください。
修正を行うたびにビルドし直します。ビルドエラーがなくなるまで繰り返します。
ステップ 4:動作の変更に対処する
動作の変更によってビルドエラーが発生することはありませんが、実行時の動作が変わる可能性があります。該当する項目をそれぞれ確認し、以前の動作に依存していたかどうかを判断してください。
影響の大きい動作の変更(最初に確認してください):
-
浮動小数点数から整数への変換が飽和変換になりました — x86/x64 では、
float/doubleから整数型への変換がラップアラウンドせず、飽和するようになりました。references/deployment-runtime-dotnet8to9.mdを参照してください。 -
EF Core:モデルの変更保留時の例外 — モデルに適用待ちの変更がある場合、
Migrate()/MigrateAsync()が例外をスローするようになりました。すべてのHasData呼び出しでDateTime.Now、DateTime.UtcNow、またはGuid.NewGuid()を検索してください。これらは固定値の定数(例:new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc))に置き換える必要があります。references/efcore-dotnet8to9.mdを参照してください。 -
EF Core:明示的なトランザクションの例外 — ユーザートランザクション内で
Migrate()を実行すると、例外がスローされるようになりました。references/efcore-dotnet8to9.mdを参照してください。 -
HttpClientFactory はデフォルトで
SocketsHttpHandlerを使用します — プライマリハンドラーをHttpClientHandlerにキャストするコードは、InvalidCastExceptionを受け取るようになります。references/serialization-networking-dotnet8to9.mdを参照してください。 -
HttpClientFactory でヘッダーがデフォルトで秘匿化されます —
Traceレベルのログに含まれるすべてのヘッダー値が秘匿化されるようになりました。references/serialization-networking-dotnet8to9.mdを参照してください。 -
環境変数がruntimeconfig.jsonより優先されます — 環境変数によるランタイム構成設定が、
runtimeconfig.jsonの設定を上書きするようになりました。references/deployment-runtime-dotnet8to9.mdを参照してください。 -
開発環境での ASP.NET Core
ValidateOnBuild/ValidateScopes—HostBuilderは開発環境で、デフォルトでDI検証を有効にするようになりました。references/aspnet-core-dotnet8to9.mdを参照してください。
確認すべきその他の動作の変更(実行時例外⚠️や、わずかな動作の違いが発生する可能性があります):
- ⚠️
FromKeyedServicesAttributeはキーなしサービスへのフォールバックを注入しなくなりました —InvalidOperationExceptionがスローされます - ⚠️ コンテナーイメージにzlibがインストールされなくなりました — システムのzlibに依存するアプリは動作しなくなります
- ⚠️ Intel CETがデフォルトで有効になりました — CET非対応のネイティブライブラリによってプロセスが終了する可能性があります
BigIntegerの最大長が(2^31) - 1ビットになりました- JSONの
nullをJsonDocumentにデシリアライズすると、C#のnullではなく、JsonValueKind.Nullを持つ非nullのJsonDocumentが返されるようになりました System.Text.Jsonのメタデータリーダーがメタデータのプロパティ名をエスケープ解除するようになりましたZipArchiveEntryの名前とコメントがUTF-8フラグに従うようになりましたIncrementingPollingCounterの初回コールバックが非同期になりましたInMemoryDirectoryInfoがファイルにrootDirを付加するようになりましたRuntimeHelpers.GetSubArrayが異なる型を返すようになりましたPictureBoxがWebExceptionではなくHttpRequestExceptionをスローするようになりましたStatusStripが異なるデフォルトのレンダラーを使用するようになりましたIMsoComponentのサポートがオプトインになりましたSafeEvpPKeyHandle.DuplicateHandleがハンドルの参照カウントを増やすようになりましたHttpClientのメトリックが無条件でserver.portを報告するようになりました- HttpClient の EventSource イベントおよび IHttpClientFactory のログで URI のクエリ文字列が秘匿化されるようになりました
dotnet watchは古いフレームワークのホットリロードと互換性がありません- WPF の
GetXmlNamespaceMapsがStringではなくHashtableを返すようになりました
ステップ 5:インフラストラクチャを更新する
-
Dockerfile:ベースイメージを更新します。.NET 9 のコンテナーイメージでは、zlib がインストールされなくなった点に注意してください。アプリで zlib が必要な場合は、Dockerfile に
RUN apt-get update && apt-get install -y zlib1gを追加します。# Before FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build FROM mcr.microsoft.com/dotnet/aspnet:8.0 # After FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build FROM mcr.microsoft.com/dotnet/aspnet:9.0 -
CI/CD パイプライン:SDK のバージョン参照を更新します。
global.jsonを使用している場合は、次のように更新します。{ "sdk": { "version": "9.0.100", "rollForward": "latestFeature" } }rollForwardポリシーを確認してください。"disable"または"latestPatch"に設定されている場合、アップグレード後に SDK が正しく解決されない可能性があります。"latestFeature"(推奨)を指定すると、SDK は最新の 9.0.x 機能バンドにロールフォワードできます。 -
Visual Studio のバージョン:.NET 9 SDK で
net9.0をターゲットにするには、VS 17.12 以降が必要です。VS 17.11 でターゲットにできるのはnet8.0以前のみです。 -
ターミナルロガー:対話型ターミナルでは、
dotnet buildはデフォルトでターミナルロガーを使用するようになりました。MSBuild のコンソール出力を解析する CI スクリプトでは、--tl:offまたはMSBUILDTERMINALLOGGER=offが必要になる場合があります。 -
dotnet workloadの出力:出力形式が変更されました。workload コマンドの出力を解析するスクリプトがあれば更新してください。 -
.NET Monitor イメージ:タグがバージョンのみの形式に簡素化されました(特定のタグを参照するコンテナーオーケストレーションに影響します)。
ステップ 6:検証する
- クリーンビルドを実行します:
dotnet build --no-incremental - すべてのテストを実行します:
dotnet test - アプリケーションをコンテナー化している場合は、コンテナーイメージをビルドしてテストします
- アプリケーションのスモークテストを行い、特に以下の点を確認します:
- BinaryFormatter の使用(実行時に例外が発生します)
- 浮動小数点数から整数への変換動作
- EF Core のマイグレーション適用
- HttpClientFactory のハンドラーキャストとログ記録
- 開発環境での DI 検証
- ランタイム構成設定(環境変数の優先順位)
- 差分を確認し、意図しない動作変更が導入されていないことを確認します
参考資料
references/ フォルダーには、テクノロジー分野ごとに整理された、破壊的変更に関する詳細情報が含まれています。移行対象のプロジェクトに関連する参考資料のみを読み込んでください:
| 参考ファイル | 読み込むタイミング |
|---|---|
references/csharp-compiler-dotnet8to9.md | 常に(C# 13 コンパイラーの破壊的変更 — レコードでの InlineArray、イテレーターのセーフコンテキスト、コレクション式のオーバーロード) |
references/core-libraries-dotnet8to9.md | 常に(すべての .NET 9 プロジェクトに適用) |
references/sdk-msbuild-dotnet8to9.md | 常に(SDK とビルドツールの変更) |
references/aspnet-core-dotnet8to9.md | プロジェクトで ASP.NET Core を使用する場合 |
references/efcore-dotnet8to9.md | プロジェクトで Entity Framework Core を使用する場合 |
references/cryptography-dotnet8to9.md | プロジェクトで System.Security.Cryptography または X.509 証明書を使用する場合 |
references/serialization-networking-dotnet8to9.md | プロジェクトで BinaryFormatter、System.Text.Json、HttpClient、またはネットワーク API を使用する場合 |
references/winforms-wpf-dotnet8to9.md | プロジェクトで Windows Forms または WPF を使用する場合 |
references/containers-interop-dotnet8to9.md | プロジェクトで Docker コンテナーまたはネイティブ相互運用(P/Invoke)を使用する場合 |
references/deployment-runtime-dotnet8to9.md | プロジェクトでランタイム構成やデプロイを使用する場合、または浮動小数点数から整数への変換がある場合 |