migrate-dotnet9-to-dotnet10 について
.NET 9 のプロジェクトやソリューションを .NET 10 へ移行するためのスキルです。コンパイラ、ランタイム、各フレームワーク、デプロイ設定の変更を確認し、ビルドとテストで検証します。
主な機能
- 01プロジェクトと SDK の状態確認
- 02ターゲットフレームワークとパッケージの更新
- 03コンパイル時の変更への対応
- 04ランタイム動作の変更確認
- 05CI/CD とデプロイ設定の更新
- 06ビルドとテストの検証
活用シーン
- 01net9.0 プロジェクトの net10.0 への移行
- 02.NET 10 SDK 導入後のエラー修正
- 03ASP.NET Core または EF Core コードの適応
- 04コンテナーや CI/CD 設定の更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dotnet/ skills --skill migrate-dotnet9-to-dotnet10インストール後、Claude Code で/migrate-dotnet9-to-dotnet10を入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/aspnet-core-dotnet9to10.mdcontainers-interop-dotnet9to10.mdcore-libraries-dotnet9to10.mdcryptography-dotnet9to10.mdcsharp-compiler-dotnet9to10.mdefcore-dotnet9to10.mdextensions-hosting-dotnet9to10.mdsdk-msbuild-dotnet9to10.mdserialization-networking-dotnet9to10.mdwinforms-wpf-dotnet9to10.md詳細
.NET 9 → .NET 10 の移行
.NET 9 のプロジェクトまたはソリューションを .NET 10 に移行し、すべての破壊的変更を体系的に解決します。移行後は net10.0 を対象とするプロジェクトとなり、問題なくビルドでき、テストに合格し、.NET 10 リリースで導入された動作上、ソース互換性上、バイナリ互換性上のすべての変更に対応できます。
使用するタイミング
TargetFrameworkをnet9.0からnet10.0に更新するとき- .NET 10 SDK の更新後にビルドエラーや新しい警告を解決するとき
- .NET 10 ランタイム、ASP.NET Core 10、または EF Core 10 の動作変更に対応するとき
- CI/CD パイプライン、Dockerfile、またはデプロイスクリプトを .NET 10 用に更新するとき
- コミュニティ製の
System.Linq.Asyncパッケージから組み込みのSystem.Linq.AsyncEnumerableに移行するとき
使用しないタイミング
- プロジェクトがすでに
net10.0を対象としており、問題なくビルドできる場合 — 移行は完了しています - .NET 8 以前からアップグレードする場合 — まず
migrate-dotnet8-to-dotnet9スキルを使用してnet9.0に到達し、その後このスキルに戻ってnet9.0→net10.0の移行を行ってください - .NET Framework から移行する場合 — これは別個の、より大規模な作業です
- .NET 10 を対象に開始する新規プロジェクトの場合(移行は不要です)
入力
| 入力 | 必須 | 説明 |
|---|---|---|
| プロジェクトまたはソリューションのパス | はい | 移行する .csproj、.sln、または .slnx のエントリポイント |
| ビルドコマンド | いいえ | ビルド方法(例:dotnet build、リポジトリのビルドスクリプト)。指定されていない場合は自動検出します |
| テストコマンド | いいえ | テストの実行方法(例:dotnet test)。指定されていない場合は自動検出します |
| プロジェクトの種類に関するヒント | いいえ | プロジェクトが ASP.NET Core、EF Core、WinForms、WPF、コンテナーなどを使用しているかどうか。指定されていない場合は PackageReferences と SDK 属性から自動検出します |
ワークフロー
読み込まれた参照ドキュメントに基づいて直接回答してください。 破壊的変更に関する情報を得るために、ファイルシステムを検索したりウェブページを取得したりしないでください。詳細な情報は参照ドキュメントに記載されています。該当する破壊的変更を特定し、具体的な修正方法を提示してください。例外: プロジェクトの依存関係にセキュリティ脆弱性(CVE)が適用される可能性がある場合は、公開済みのセキュリティ勧告を確認してください。参照ドキュメントには、公開後に判明した CVE が含まれていない場合があります。
コミット戦略: 論理的な区切りごとにコミットしてください。TFM の更新後(ステップ 2)、ビルドエラーの解決後(ステップ 3)、動作変更への対応後(ステップ 4)、インフラストラクチャの更新後(ステップ 5)にコミットします。各コミットの範囲が明確になり、レビューしやすくなります。
ステップ 1:プロジェクトを評価する
- プロジェクトのビルド方法とテスト方法を特定します。ビルドスクリプト、
.sln/.slnxファイル、または個別の.csprojファイルを確認します。 dotnet --versionを実行して、.NET 10 SDK がインストールされていることを確認します。インストールされていない場合は、作業を停止してユーザーに伝えてください。- 次の項目を調べて、プロジェクトで使用されている技術分野を特定します。
- SDK 属性:
Microsoft.NET.Sdk.Web→ ASP.NET Core、<UseWPF>または<UseWindowsForms>を含むMicrosoft.NET.Sdk.WindowsDesktop→ WPF/WinForms - PackageReferences:
Microsoft.EntityFrameworkCore.*→ EF Core、Microsoft.Data.Sqlite→ Sqlite、Microsoft.Extensions.Hosting→ Generic Host/BackgroundService - Dockerfile の有無 → コンテナー関連の変更が該当
- P/Invoke またはネイティブ相互運用の使用 → 相互運用関連の変更が該当
System.Linq.Asyncパッケージ参照 → AsyncEnumerable への移行が必要- ポリモーフィズムを用いた
System.Text.Jsonの使用 → シリアル化関連の変更が該当
- SDK 属性:
- 関連する参照ドキュメントを記録します(ステップ 3 の参照ドキュメント読み込み表を参照)。
- 現在の
net9.0を対象にクリーンビルド(dotnet build --no-incrementalを実行するか、bin/objを削除)を行い、クリーンなベースラインを確立します。既存の警告があれば記録します。
ステップ 2:ターゲットフレームワークを更新する
-
各
.csproj(または一元管理している場合はDirectory.Build.props)で、次のように変更します。<TargetFramework>net9.0</TargetFramework>変更後:
<TargetFramework>net10.0</TargetFramework>マルチターゲットプロジェクトの場合は、
<TargetFrameworks>にnet10.0を追加するか、net9.0を置き換えます。 -
すべての
Microsoft.Extensions.*、Microsoft.AspNetCore.*、Microsoft.EntityFrameworkCore.*およびその他の Microsoft パッケージ参照を、バージョン 10.0.x に更新します。Central Package Management(Directory.Packages.props)を使用している場合は、そちらでバージョンを更新します。 -
dotnet restoreを実行します。次の点を確認してください。- NU1510:NuGet によって直接参照が削除されました。パッケージが共有フレームワークに含まれるようになった可能性があります。その場合は、明示的な
<PackageReference>を削除してください。 - バージョンを指定していない PackageReference はエラーになります — すべての
<PackageReference>にVersionを指定する必要があります(または CPM を使用してください)。 - 推移的パッケージに対する NuGet の監査(
dotnet restoreで推移的な依存関係も監査されるようになりました)— 新たに表示された脆弱性の警告を確認してください。
- NU1510:NuGet によって直接参照が削除されました。パッケージが共有フレームワークに含まれるようになった可能性があります。その場合は、明示的な
-
クリーンビルドを実行します。すべてのエラーと新しい警告を収集します。これらはステップ 3 で対処します。
ステップ 3:ビルドエラーとソース互換性のない変更を解決する
コンパイルエラーと新しい警告に、順を追って対処します。プロジェクトの種類に応じて、適切なリファレンスドキュメントを読み込みます。
| プロジェクトで使用しているもの… | リファレンスを読み込む |
|---|---|
| .NET 10 プロジェクト全般 | references/csharp-compiler-dotnet9to10.md |
| .NET 10 プロジェクト全般 | references/core-libraries-dotnet9to10.md |
| .NET 10 プロジェクト全般 | references/sdk-msbuild-dotnet9to10.md |
| ASP.NET Core | references/aspnet-core-dotnet9to10.md |
| Entity Framework Core | references/efcore-dotnet9to10.md |
| 暗号化 API | references/cryptography-dotnet9to10.md |
| Microsoft.Extensions.Hosting、BackgroundService、構成 | references/extensions-hosting-dotnet9to10.md |
| System.Text.Json、XmlSerializer、HttpClient、MailAddress、Uri | references/serialization-networking-dotnet9to10.md |
| Windows Forms または WPF | references/winforms-wpf-dotnet9to10.md |
| Docker コンテナー、単一ファイルアプリ、ネイティブ相互運用 | references/containers-interop-dotnet9to10.md |
確認すべき、ソース互換性に関わる主な変更:
-
System.Linq.Asyncの競合 —System.Linq.Asyncパッケージ参照を削除するか、v7.0.0 にアップグレードします。推移的に取り込まれている場合は、<ExcludeAssets>compile</ExcludeAssets>を追加します。必要に応じて、SelectAwaitの呼び出しをSelectに変更します。 -
新たに追加された非推奨化の警告(SYSLIB0058–SYSLIB0062):
SYSLIB0058:SslStream.KeyExchangeAlgorithm/CipherAlgorithm/HashAlgorithmをNegotiatedCipherSuiteに置き換えます。古いプロパティを弱い TLS 暗号スイートの拒否に使用していた場合は、新しい API を使って同等の検証ロジックを維持してください。SYSLIB0059:SystemEvents.EventsThreadShutdownをAppDomain.ProcessExitに置き換えます。SYSLIB0060:Rfc2898DeriveBytesのコンストラクターをRfc2898DeriveBytes.Pbkdf2に置き換えます。SYSLIB0061:IComparer<TSource>を受け取るQueryable.MaxBy/MinByオーバーロードを、IComparer<TKey>を受け取るものに置き換えます。SYSLIB0062:XsltSettings.EnableScriptの使用を置き換えます。
-
C# 14 のプロパティアクセサーにおける
fieldキーワード — 識別子fieldは、プロパティのget/set/initアクセサー内でコンテキストキーワードになりました。fieldという名前のローカル変数は CS9272(エラー)を引き起こします。this.を付けずに参照される、fieldという名前のクラスメンバーは CS9258(警告)を引き起こします。名前を変更する(例:fieldValue)か、@fieldとしてエスケープして修正してください。references/csharp-compiler-dotnet9to10.mdを参照してください。 -
C# 14 のコンテキストキーワード
extension—extensionという名前の型、エイリアス、または型パラメーターは使用できません。名前を変更するか、@extensionとしてエスケープしてください。 -
span パラメーターを含む C# 14 のオーバーロード解決 — 配列に対する
.Contains()を含む式ツリーは、Enumerable.ContainsではなくMemoryExtensions.Containsにバインドされる場合があります。配列に対するEnumerable.Reverseは、インプレースのSpan拡張メソッドに解決される場合があります。IEnumerable<T>にキャストするか、.AsEnumerable()を使用するか、静的メソッドを明示的に呼び出して修正してください。詳細はreferences/csharp-compiler-dotnet9to10.mdを参照してください。 -
ASP.NET Core の非推奨化(該当する場合):
WebHostBuilder、IWebHost、WebHostは非推奨です —Host.CreateDefaultBuilderまたはWebApplication.CreateBuilderに移行してくださいIActionContextAccessor/ActionContextAccessorは非推奨ですWithOpenApi拡張メソッドは非推奨ですIncludeOpenAPIAnalyzersプロパティは非推奨ですIPNetworkとForwardedHeadersOptions.KnownNetworksは非推奨です- Razor のランタイムコンパイルは非推奨です
Microsoft.Extensions.ApiDescription.Clientパッケージは非推奨ですMicrosoft.OpenApiv2.x の破壊的変更 —Microsoft.AspNetCore.OpenApi 10.0は、名前空間とモデルを再構成したMicrosoft.OpenApiv2.x を取り込みます。OpenApiString/OpenApiAny型は削除されました(JsonNodeを使用してください)。OpenApiSecurityScheme.ReferenceはOpenApiSecuritySchemeReferenceに置き換えられました。OpenAPI モデルオブジェクトのコレクションが null の場合があり、OpenApiSchema.Nullableは削除されました。移行パターンについてはreferences/aspnet-core-dotnet9to10.mdを参照してください。
-
SDK の変更:
dotnet new slnの既定の形式が SLNX になりました — 従来の形式が必要な場合は--format slnを使用してください- ファイルレベルのディレクティブで二重引用符は使用できなくなりました
- .NET SDK から
dnx.ps1が削除されました dotnet restoreではproject.jsonがサポートされなくなりました
-
EF Core のソースコード変更(該当する場合)— 以下については
references/efcore-dotnet9to10.mdを参照してください。ExecuteUpdateAsyncが通常のラムダ式を受け入れるようになりました(式ツリー構築コードを書き換える必要があります)IDiscriminatorPropertySetConventionのシグネチャが変更されましたIRelationalCommandDiagnosticsLoggerのメソッドにlogCommandTextパラメーターが追加されました
-
WinForms/WPF のソースコード変更(該当する場合):
- WPF と WinForms の両方を参照するアプリケーションでは、
MenuItem型とContextMenu型を明確に区別する必要があります HtmlElement.InsertAdjacentElementのパラメーター名が変更されました- WPF では、空の
ColumnDefinitionsとRowDefinitionsが使用できなくなりました
- WPF と WinForms の両方を参照するアプリケーションでは、
-
暗号化のソースコード変更(該当する場合):
MLDsaとSlhDsaのメンバー名がSecretKeyからPrivateKeyに変更されました(例:ExportMLDsaSecretKey→ExportMLDsaPrivateKey、SecretKeySizeInBytes→PrivateKeySizeInBytes)Rfc2898DeriveBytesコンストラクターは非推奨です(SYSLIB0060)—Rfc2898DeriveBytes.Pbkdf2(password, salt, iterations, hashAlgorithm, outputLength)の静的メソッドに置き換えてくださいCoseSigner.Keyが null になり得るようになりました — 使用前に null かどうかを確認してくださいX509Certificate.GetKeyAlgorithmParameters()とPublicKey.EncodedParametersは null を返す場合があります- 環境変数名が
CLR_OPENSSL_VERSION_OVERRIDEからDOTNET_OPENSSL_VERSION_OVERRIDEに変更されました
修正をひとまとまり適用するたびに、再度ビルドしてください。ビルドエラーがなくなるまで繰り返してください。
ステップ 4:動作の変更に対応する
動作の変更によってビルドエラーは発生しませんが、実行時の動作が変わる可能性があります。該当する項目をそれぞれ確認し、以前の動作に依存していたかどうかを判断してください。
影響の大きい動作の変更(先に確認してください):
-
SIGTERM シグナルの処理が削除されました — .NET ランタイムは、デフォルトの SIGTERM ハンドラーを登録しなくなりました。SIGTERM 時に
AppDomain.ProcessExitまたはAssemblyLoadContext.Unloadingが発生することに依存している場合:- ASP.NET Core と Generic Host のアプリには影響しません(独自のハンドラーを登録します)
- Generic Host を使用しないコンソールアプリとコンテナー化されたアプリでは、
PosixSignalRegistration.Create(PosixSignal.SIGTERM, _ => Environment.Exit(0))を明示的に登録する必要があります
-
BackgroundService.ExecuteAsync はバックグラウンドスレッドで最初から最後まで実行されます — 最初の
awaitより前の同期処理によって、起動がブロックされなくなりました。起動順序が重要な場合は、そのコードをStartAsyncまたはコンストラクターに移すか、IHostedLifecycleServiceを実装してください。 -
構成の null 値が保持されるようになりました — JSON の
null値は、空の文字列に変換されなくなりました。デフォルト以外の値で初期化されたプロパティは、nullで上書きされます。構成のバインドコードを確認してください。 -
Microsoft.Data.Sqlite の DateTimeOffset の変更(すべて影響大):
- オフセットを指定しない
GetDateTimeOffsetは UTC として扱うようになりました(以前はローカル時刻として扱われていました) - REAL 列への
DateTimeOffsetの書き込みでは、最初に UTC に変換されるようになりました - オフセットを指定した
GetDateTimeは、DateTimeKind.Utcの UTC を返すようになりました - 回避策:一時的な回避策として
AppContext.SetSwitch("Microsoft.Data.Sqlite.Pre10TimeZoneHandling", true)を使用します
- オフセットを指定しない
-
EF Core のパラメーター化コレクション — コレクションに対する
.Contains()は、JSON/OPENJSON の代わりに複数のスカラー パラメーターを使用するようになりました。大規模なコレクションでは、クエリのパフォーマンスに影響する可能性があります。回避策:UseParameterizedCollectionMode(ParameterTranslationMode.Parameter)で元に戻します。 -
Azure SQL での EF Core の JSON データ型 — Azure SQL で互換性レベルが 170 以上の場合、
nvarchar(max)の代わりにjsonデータ型を使用するようになりました。既存の列を変更するマイグレーションが生成されます。回避策:互換性レベルを 160 に設定するか、HasColumnType("nvarchar(max)")を明示的に使用します。 -
System.Text.Json のプロパティ名の競合チェック — メタデータ名(
$type、$id、$ref)と競合するプロパティを持つポリモーフィック型では、InvalidOperationExceptionがスローされるようになりました。競合するプロパティに[JsonIgnore]を追加してください。
確認が必要なその他の動作の変更:
BufferedStream.WriteByteは暗黙的にフラッシュしなくなりました — 必要に応じて、明示的なFlush()呼び出しを追加してください- デフォルトのトレースコンテキスト伝播が W3C 標準に更新されました
DriveInfo.DriveFormatは、実際の Linux ファイルシステムの種類を返すようになりました- LDAP の
DirectoryControlの解析がより厳格になりました - デフォルトの .NET コンテナーイメージが Debian から Ubuntu に切り替わりました(Debian イメージは提供されなくなりました)
- 単一ファイルアプリは、デフォルトでは実行ファイルのディレクトリ内でネイティブ ライブラリを検索しなくなりました
DllImportSearchPath.AssemblyDirectoryはアセンブリのディレクトリのみを検索しますMailAddressは連続するピリオドを検証するようになりました- ブラウザーの HTTP クライアントでは、HTTP レスポンスのストリーミングがデフォルトで有効になりました
Uriの長さ制限がなくなりました — 信頼できないソースからの過大な入力をUriで拒否していた場合は、明示的な長さ検証を追加してください- 既知の API エンドポイントでは Cookie によるログインリダイレクトが無効になりました(ASP.NET Core)
XmlSerializerは[Obsolete]プロパティを無視しなくなりました — 機密データを含む可能性のある非推奨プロパティを確認し、意図しないデータの公開を防ぐために[XmlIgnore]を追加してくださいdotnet restoreは推移的パッケージを監査しますdotnet watchは標準出力ではなく標準エラーにログを出力しますdotnetCLI コマンドは、コマンドに関係しないデータを標準エラーにログ出力します- NuGet に関するさまざまな動作の変更があります(
references/sdk-msbuild-dotnet9to10.mdを参照) StatusStripはデフォルトで System RenderMode を使用します(WinForms)TreeViewのチェックボックス画像の切り詰めが修正されました(WinForms)DynamicResourceの誤った使用によってクラッシュが発生します(WPF)
ステップ 5: インフラストラクチャを更新する
-
Dockerfile: ベースイメージを更新します。デフォルトのタグは Debian ではなく Ubuntu を使用するようになりました。Debian イメージは .NET 10 向けには出荷されなくなりました。
# Before FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build FROM mcr.microsoft.com/dotnet/aspnet:9.0 # After FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build FROM mcr.microsoft.com/dotnet/aspnet:10.0 -
CI/CD パイプライン: SDK バージョンの参照を更新します。
global.jsonを使用している場合は、次を更新します:{ "sdk": { "version": "10.0.100" } } -
環境変数の名前が変更されました:
DOTNET_OPENSSL_VERSION_OVERRIDEが古い名前を置き換えますDOTNET_ICU_VERSION_OVERRIDEが古い名前を置き換えますNUGET_ENABLE_ENHANCED_HTTP_RETRYは削除されました
-
OpenSSL の要件: Unix では OpenSSL 1.1.1 以降が必須になりました。macOS では OpenSSL の暗号プリミティブはサポートされなくなりました。
-
ソリューションファイルの形式: スクリプトで
dotnet new slnを使用している場合、SLNX 形式を生成するようになったことに注意してください。古い形式が必要な場合は--format slnを渡してください。
ステップ 6: 検証する
- 完全なクリーンビルドを実行します:
dotnet build --no-incremental - すべてのテストを実行します:
dotnet test - アプリケーションがコンテナ化されている場合は、コンテナイメージをビルドしてテストします
- アプリケーションのスモークテストを実行し、特に次の点に注意してください:
- シグナル処理 / グレースフルシャットダウンの動作
- バックグラウンドサービスの起動順序
- null 値を使用した構成のバインド
- Sqlite での日付/時刻の処理
- ポリモーフィック型を使用した JSON シリアル化
- コレクションに対して
.Contains()を使用する EF Core クエリ
- セキュリティレビュー — 移行によってセキュリティ制御が弱まっていないことを確認します:
SslStreamAPI の移行 (SYSLIB0058) 後も TLS 暗号スイートの検証ロジックが維持されている- 機密データを含む廃止されたプロパティがシリアル化から除外されている (
[XmlIgnore]、[JsonIgnore]) - 長さのゲートとして
Uriが使用されていた場合、入力検証が依然としてサイズ超過の URI を拒否する - 例外ハンドラーが
trueを返す前に、セキュリティに関連するテレメトリ (認証失敗、アクセス違反) を出力する - 接続文字列が、バージョン情報を漏らさない明示的な
Application Nameを設定している dotnet restoreの監査が抑制されるのではなく、対処されている
- 差分を確認し、意図しない動作変更が導入されていないことを確認します
参照ドキュメント
references/ フォルダーには、技術領域別に整理された詳細な破壊的変更の情報が含まれています。移行対象のプロジェクトに関連する参照のみを読み込んでください:
| 参照ファイル | 読み込むタイミング |
|---|---|
references/csharp-compiler-dotnet9to10.md | 常に (C# 14 コンパイラーの破壊的変更 — field キーワード、extension キーワード、span オーバーロード) |
references/core-libraries-dotnet9to10.md | 常に (すべての .NET 10 プロジェクトに適用されます) |
references/sdk-msbuild-dotnet9to10.md | 常に (SDK およびビルドツールの変更) |
references/aspnet-core-dotnet9to10.md | プロジェクトが ASP.NET Core を使用している場合 |
references/efcore-dotnet9to10.md | プロジェクトが Entity Framework Core または Microsoft.Data.Sqlite を使用している場合 |
references/cryptography-dotnet9to10.md | プロジェクトが System.Security.Cryptography または X.509 証明書を使用している場合 |
references/extensions-hosting-dotnet9to10.md | プロジェクトが Generic Host、BackgroundService、または Microsoft.Extensions.Configuration を使用している場合 |
references/serialization-networking-dotnet9to10.md | プロジェクトが System.Text.Json、XmlSerializer、HttpClient、またはネットワーク API を使用している場合 |
references/winforms-wpf-dotnet9to10.md | プロジェクトが Windows Forms または WPF を使用している場合 |
references/containers-interop-dotnet9to10.md | プロジェクトが Docker コンテナ、単一ファイル発行、またはネイティブ相互運用 (P/Invoke) を使用している場合 |