はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【C#】PackageReferenceとProjectReferenceでビルドの際に求められる.NET SDKの考え方の違い

はじめに

PcakgeReferenceProjectReferenceを利用した下記のcsporjがあるとします。それぞれのプロジェクトをビルドする際に必要な.NET SDKのバージョンは何か分かるでしょうか?

<!-- パターン1.csproj -->
<TargetFramework>net8.0</TargetFramework>
...
<ProjectReference Include="../Hoge/Hoge.csproj" />
<!-- パターン2.csproj -->
<TargetFramework>net8.0</TargetFramework>
...
<PackageReference Include="Hoge" Version="1.0.0" />
<!-- パターン1とパターン2から参照されているプロジェクト -->
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>

答えはProjectReferenceの方はnet9で、PackageReferencenet8です。またややこしいことに、ビルドするのにnet9が必要でも実際にビルドされるtfmnet8になります。

仕組みを理解すれば大したことではないのですが、割と初見殺しな気がするのでそこら辺について書き残しておきます。

概要

端的にまとめると

  • ProjectReferenceは依存先プロジェクトもビルドするためより新しいバージョンの.NET SDKを要求する
  • PackageReferenceはビルド済みのライブラリを利用するため自身のプロジェクトをビルドできるSDKがあれば問題ない

という感じです。

PackageReference

PackageReference既に特定のTargetFramework向けにビルド済みのアセンブリを利用します。(netstandard2.1など互換性のある下位のアセンブリを利用することもある)

ですのでビルドに必要となる.NET SDKは、あくまでビルドを実行するプロジェクト自身のTargetFrameworkに対応していればよいのです。

ProjectReference

ProjectReferenceはNuGetパッケージとは異なり、ソースコードレベルでの依存となります。ProjectReferenceを持つプロジェクトをビルドすると、依存先のプロジェクトも一緒にビルドされます。

つまりビルドに必要となる.NET SDKは、参照関係にあるすべてのプロジェクトのTargetFrameworkをサポートするバージョンが要求されます。global.jsonの影響がある可能性もあるかもですが、基本的に最新のものを入れておけばビルドできるはずです。

さいごに

私の場合ローカルでは色々なバージョンの.NET SDKが入っているので問題になることは少ないのですが、特にCI/CDで.NET SDKを用意する場合では気をつけたほうが良いでしょう。ProjectReferenceの場合は依存先も調べないといけないので、結構分かりづらくご注意ください。