最新の .NET では、複数のオペレーティング システムとデバイスがサポートされます。 .NET のオープンソース ライブラリでは、開発者が Azure でホストされる ASP.NET Web サイトを構築しているか、Unity で .NET ゲームを構築しているかに関わらず、できるだけ多くの開発者をサポートすることが重要です。
.NET および .NET Standard のターゲット
.NET および .NET Standard のターゲットは、.NET ライブラリにクロスプラットフォーム サポートを追加する最善の方法です。
- .NET Standard は、すべての .NET 実装で使用できる .NET API の仕様です。 .NET Standard をターゲットにすることで、特定のバージョンの .NET Standard 内にある API を使用するように制約されるライブラリを作成できます。これは、そのバージョンの .NET Standard を実装するすべてのプラットフォームで使用できることを意味します。
- .NET 6-8 は、.NET 実装です。 各バージョンは、Windows デスクトップ アプリ、クロスプラットフォーム コンソール アプリ、クラウド サービス、Web サイトに使用できる機能と API の統一されたセットを備えた単一の製品です。
.NET と .NET Standard を比較する方法の詳細については、「.NET 5 と .NET Standard」を参照してください。
プロジェクトが .NET または .NET Standard を対象とし、正常にコンパイルされた場合でも、ライブラリがすべてのプラットフォームで正常に実行されることは保証されません。
- プラットフォーム固有の API は、他のプラットフォームでは失敗します。 たとえば、Microsoft.Win32.Registry は Windows では成功し、他の OS で使用する場合、PlatformNotSupportedException がスローされます。
- API の動作はそれぞれ異なる場合があります。 たとえば、アプリケーションによって iOS や UWP で Ahead Of Time コンパイルが使用される場合、リフレクション API のパフォーマンス特性は異なります。
ヒント
考えられる問題の検出に役立つプラットフォーム互換性アナライザーが .NET チームから提供されます。
✔️ まず、netstandard2.0
ターゲットを含めることから始めてください。
ほとんどの汎用ライブラリでは、.NET Standard 2.0 外の API は必要ありません。 .NET Standard 2.0 はすべての最新のプラットフォームでサポートされており、1 つのターゲットで複数のプラットフォームをサポートする場合に推奨される方法です。 .NET Framework をサポートする必要がない場合は、.NET Standard 2.1 をターゲットにすることもできます。
✔️ 最新の .NET で導入された新しい API が必要な場合は、net6.0
ターゲット以降を含めてください。
.NET 6 以降のアプリでは
netstandard2.0
ターゲットを使用できるため、net6.0
は必要ありません。 新しい .NET API を使用する場合は、net6.0
、net7.0
、net8.0
またはnet9.0
を明示的にターゲットにする必要があります。
ターゲットを❌含めることは避けてください。netstandard1.x
.NET Standard 1.x は、NuGet パッケージの細分化されたセットとして配布されます。これにより、大規模なパッケージ依存関係グラフが作成され、ビルド時に多数のパッケージがダウンロードされることになります。 最新の .NET 実装は .NET Standard 2.0 をサポートしています。 特に古いプラットフォームをターゲットにする必要がある場合は、.NET Standard 1.x のみをターゲットにしてください。
✔️ netstandard2.0
ターゲットを必要とする場合は、netstandard1.x
ターゲットを含めてください。
.NET Standard 2.0 をサポートするすべてのプラットフォームでは
netstandard2.0
ターゲットを使用し、より小さなパッケージ グラフを作成することで利点が得られますが、古いプラットフォームは引き続き動作し、netstandard1.x
ターゲットを使用するようにフォールバックします。
❌ ライブラリがプラットフォーム固有のアプリ モデルに依存している場合は、.NET Standard ターゲットを含めないでください。
たとえば、UWP コントロール ツールキット ライブラリは、UWP でのみ使用できるアプリ モデルによって異なります。 アプリ モデル固有の API は .NET Standard では使用できません。
❌プロジェクトまたは依存関係が複数のターゲットの場合は、netstandard2.0
に対して発行しないでください。
netstandard2.0
はランタイムではなく、マルチターゲット プロジェクトでは、他のフレームワークで実行するときに必要なランタイム フレームワーク固有のライブラリが提供されます。
マルチターゲット
場合によっては、ご利用のライブラリからフレームワーク固有の API にアクセスする必要があります。 フレームワーク固有の API を呼び出す最善の方法は、1 つだけでなく、多くの .NET ターゲット フレームワークに対するプロジェクトを構築する、マルチ ターゲットを使用することです。
コンシューマーが個々のフレームワークに対して構築しなくても済むように、.NET Standard 出力に加え、1 つ以上のフレームワーク固有の出力が得られるようにします。 マルチターゲットを使用すると、単一の NuGet アセンブリ内ですべてのアセンブリがパッケージ化されます。 その後、コンシューマーは同じパッケージを参照でき、NuGet では適切な実装が選択されます。 .NET Standard ライブラリはフォールバック ライブラリとして機能します。このライブラリは、NuGet パッケージでフレームワーク固有の実装が提供される場合を除き、あらゆる場所で使用されます。 マルチ ターゲットでは、コードで条件付きコンパイルを使用して、フレームワーク固有の API を呼び出すことができます。
✔️ .NET Standard に加え、.NET 実装をターゲットにすることを検討してください。
.NET 実装をターゲットにすることで、.NET Standard 外にあるプラットフォーム固有の API を呼び出すことができます。
これを行うときに、.NET Standard のサポートを放棄しないでください。 代わりに、実装から分離させて、機能 API を提供します。 これにより、ライブラリを任意の場所で使用でき、ランタイムの機能を際立たせることができます。
public static class GpsLocation
{
// This project uses multi-targeting to expose device-specific APIs to .NET Standard.
public static async Task<(double latitude, double longitude)> GetCoordinatesAsync()
{
#if NET462
return CallDotNetFrameworkApi();
#elif WINDOWS_UWP
return CallUwpApi();
#else
throw new PlatformNotSupportedException();
#endif
}
// Allows callers to check without having to catch PlatformNotSupportedException
// or replicating the OS check.
public static bool IsSupported
{
get
{
#if NET462 || WINDOWS_UWP
return true;
#else
return false;
#endif
}
}
}
✔️ プロジェクトにライブラリまたはパッケージの依存関係がある場合、ソース コードがすべてのターゲットで同じであっても、マルチターゲットを検討します。
プロジェクトの依存パッケージ (直接または下流) は、ターゲット フレームワークごとに異なるバージョンの依存アセンブリ内にラップされながら、同じコード API を使用する場合があります。 特定のターゲットを追加すると、コンシューマーはアセンブリ バインディング リダイレクトを追加または更新する必要がなくなります。
❌ ソース コードがすべてのターゲットに対して同じであり、プロジェクトにライブラリまたはパッケージの依存関係がない場合は、マルチターゲットおよび .NET Standard のターゲット設定を避けてください。
.NET Standard アセンブリは、NuGet によって自動的に使用されます。 個々の .NET 実装をターゲットにすると、
*.nupkg
サイズが増えるだけで、利点はありません。
✔️ net462
ターゲットを提供する場合、netstandard2.0
のターゲットを追加することを検討してください。
.NET Framework から .NET Standard 2.0 を使用する場合、いくつかの問題がありますが、.NET Framework 4.7.2 で対処されました。 .NET Framework 4.6.2 から 4.7.1 を引き続き使用している開発者に、.NET Framework 4.6.2 用にビルドされているバイナリを提供することで、その開発者のエクスペリエンスを向上させることができます。
NuGet パッケージを使用してご利用のライブラリの配布を✔️ 実施してください。
NuGet では開発者にとって最適なターゲットが選択され、開発者が適切な実装を選ぶ必要はなくなります。
✔️ マルチターゲットにする場合は、プロジェクト ファイルの TargetFrameworks
プロパティを使用してください。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- This project will output netstandard2.0 and net462 assemblies -->
<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
</PropertyGroup>
</Project>
❌ アセンブリ名を変更したり、ライブラリがコンパイルする TFM ごとに異なるアセンブリ名を使用したりしないでください。 ライブラリ間の依存関係により、TFM ごとに異なるアセンブリ名を持つマルチターゲットがパッケージの使用者に影響を与える可能性があります。 アセンブリはすべての TFM で同じ名前である必要があります。
古いターゲット
.NET は、サポート対象外となった .NET Framework のバージョンや、一般的に使用されなくなったプラットフォームをターゲットにすることをサポートします。 できるだけ多くのターゲットでライブラリを動作させる価値はありますが、API の欠落を回避する必要がある場合、オーバーヘッドが大幅に増える可能性があります。 リーチと制限を考慮すると、特定のフレームワークは、ターゲットにする価値がありません。
❌ Portable Class Library (PCL) ターゲットを含めないでください。 たとえば、「 portable-net45+win8+wpa81+wp8
」のように入力します。
.NET Standard は、クロスプラットフォームの .NET ライブラリをサポートする最新の方法であり、PCL に代わるものです。
❌ サポートされなくなった .NET プラットフォームのターゲットを含めないでください。 たとえば、SL4
、WP
のようになります。
.NET