C#8は.NET Frameworkをサポートしていますか?


129

Visual Studio 2019 Advanced Build設定では、C#8は.NET Frameworkプロジェクトでは利用できません(以下の図のように).NET Core 3.0プロジェクトでのみ利用できます。

ここに画像の説明を入力してください

C#8は.NET Frameworkをサポートしていますか?

回答:


235

はい、C#8は、.NET FrameworkおよびVisual Studio 2019の.NET Core 3.0 / .NET Standard 2.1(またはNugetパッケージインストールする場合は古いバージョンのVisual Studio )より古い他のターゲットで使用できます

言語バージョン8.0は、csprojファイルでに設定する必要があります。

すべてではありませんが、ほとんどの機能は、対象となるフレームワークにかかわらず利用できます。


機能する機能

次の機能は構文の変更のみです。フレームワークに関係なく機能します。

機能させることができる機能

これらには、.NET Frameworkにない新しい型が必要です。これらは、 "polyfill" Nugetパッケージまたはコードファイルと組み合わせてのみ使用できます。

デフォルトのインターフェースメンバー-機能しません

既定のインターフェイスメンバーは.NET Frameworkでコンパイルされず、CLRでランタイムを変更する必要があるため、機能しません。.NET Coreが前進するため、.NET CLRはフリーズされました。

何が機能し、何が機能しないか、および可能なポリフィルの詳細については、Stuart Langの記事、C#8.0および.NET Standard 2.0-Doing Unsupported Thingsを参照してください


コード

.NET Framework 4.8を対象とし、C#8のnull許容参照型を使用する次のC#プロジェクトは、Visual Studio 16.2.0でコンパイルされます。.NET標準クラスライブラリテンプレートを選択し、それを編集して.NET Frameworkをターゲットにすることで作成しました。

.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net48</TargetFrameworks>
    <LangVersion>8.0</LangVersion>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

.cs:

namespace ClassLibrary1
{
    public class Class1
    {
        public string? NullableString { get; set; }
    }
}

次に、レガシー.csproj形式を使用して.NET Framework 4.5.2 WinFormsプロジェクトを試し、同じnull許容参照型プロパティを追加しました。Visual Studio Advanced Build設定ダイアログ(16.3では無効)で言語タイプを変更してlatest、プロジェクトを保存しました。もちろん、この時点ではビルドされません。テキストエディターでプロジェクトファイルを開き、ビルド構成に変更latestpreviewましたPropertyGroup

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   <LangVersion>preview</LangVersion>

次に<Nullable>enable</Nullable>、メインにを追加して、null許容の参照型のサポートを有効にしましたPropertyGroup

<PropertyGroup>
   <Nullable>enable</Nullable>

プロジェクトをリロードしてビルドします。


悲惨な詳細

この回答が最初に書かれたとき、C#8はプレビュー段階にあり、多くの探偵が関与していました。後世のためにここにその情報を残します。すべての悲惨な詳細を知る必要がない場合は、遠慮なくスキップしてください。

C#言語は、歴史的にはほとんどフレームワークに依存していません。つまり、古いバージョンのフレームワークをコンパイルできますが、一部の機能には新しいタイプまたはCLRサポートが必要です。

ほとんどのC#愛好家は、C#8の特定の機能にプラットフォームの依存関係があることを説明する、Mads Torgersenによるブログエントリ「Building C#8.0」を読んだことでしょう。

非同期ストリーム、インデクサー、範囲はすべて.NET Standard 2.1の一部となる新しいフレームワークタイプに依存しています... .NET Core 3.0とXamarin、Unity、Monoはすべて.NET Standard 2.1を実装しますが、.NET Framework 4.8はない。つまり、これらの機能を使用するために必要な型は、.NET Framework 4.8では使用できません。

これは、C#7で導入されたValue Tuplesに少し似ています。その機能には、ValueTuple4.7より前のNET Frameworkバージョンまたは2.0より前の.NET Standardでは利用できなかった新しいタイプ(構造)が必要でした。ただし、値のタプルなしで、またはSystem.ValueTuple Nugetパッケージをインストールすることにより、C#7を古いバージョンの.NETで引き続き使用できます。Visual Studioはこれを理解し、すべてが世界的に順調でした。

しかし、マッズも書いている:

このため、C#8.0の使用は、.NET Standard 2.1を実装するプラットフォームでのみサポートされています。

...これがtrueの場合、任意のバージョンの.NET FrameworkでC#8を使用することを除外し、実際に.NET Standard 2.0ライブラリでも、最近になってライブラリコードのベースラインターゲットとして使用することが推奨されました。3.0よりも古い.NET Coreバージョンでも.NET Standard 2.0しかサポートしていないため、これを使用することもできません。

調査が始まりました!-

  • ジョンスキートはC#8使用野田時のアルファ版がある行く準備ができて、.NETの標準2.0のみを対象としています。彼は明らかに、C#8 / .NET Standard 2.0が.NETファミリのすべてのフレームワークをサポートすることを期待しています。(Jonのブログ投稿「null許容可能な参照型の最初のステップ」も参照してください)。

  • Microsoftの従業員はVisual Studio UI for C#8 nullable参照型についてGitHubcsproj話し合っており、レガシー(以前の.NET Core SDK形式csproj)をサポートする予定であると述べられています。これは、C#8が.NET Frameworkで使用できることを非常に強く示しています。[Visual Studio 2019の言語バージョンのドロップダウンが無効になり、.NETがC#7.3に関連付けられたので、今は彼らがこれに逆戻りすると思います]

  • 有名なブログ投稿の直後に、GitHubスレッドがクロスプラットフォームサポートについて議論しました。浮かび上がった重要な点は、.NET Standard 2.1には、インターフェイスのデフォルトの実装がサポートされていることを示すマーカーが含まれることです。この機能には、.NET Frameworkで利用できないCLRの変更が必要です。Microsoftの.NETチームのプログラムマネージャーであるImmo Landwerthからの重要な部分は次のとおりです。

    コンパイラー(C#など)は、このフィールドの存在を使用して、デフォルトのインターフェース実装を許可するかどうかを決定することが期待されています。フィールドが存在する場合、ランタイムは結果のコードをロードして実行できると期待されます。

  • これはすべて、「C#8.0は.NET Standard 2.1を実装するプラットフォームでのみサポートされている」と単純化しすぎており、C#8は.NET Frameworkをサポートすることを示していますが、不確実性が非常に高いため、GitHub質問し、HaloFourが答えました:

    IIRCは、ランタイムの変更が必要なため、.NET Frameworkに確実に表示されない唯一の機能はDIM(デフォルトのインターフェースメソッド)です。他の機能は、.NET Frameworkに追加されない可能性があるクラスの形状によって駆動されますが、独自のコードまたはNuGet(範囲、インデックス、非同期イテレータ、非同期廃棄)を通じてポリフィルできます。

  • Victor Derksは、「より複雑なnullableのユースケースを設計するために必要な新しいnullableの属性は、.NET Core 3.0および.NET Standard 2.1に同梱されているSystem.Runtime.dllでのみ使用できます。 4.8インチ

  • しかし、IMMO Landwerthはコメント記事の下の「タイプは、完全に汎用のか、nullで私たちのようなAPIの大半は、任意のカスタム属性を必要としなかった」というのNullable参照型試してみてください

  • Ben Hall氏は、GitHub でCore 3.0の外部でのnull可能属性の可用性の問題を提起し、Microsoftの従業員からの以下のコメントに注目してください。

C#8は、.net core 3.0および.net standard 2.1でのみ完全にサポートされます。.net core 2.1でC#8を使用するようにプロジェクトファイルを手動で編集する場合、サポートされていない領域にいます。一部のC#8機能はたまたまうまく機能し、一部のC#8機能はあまり機能しません(パフォーマンスの低下など)、一部のC#8機能は余分なハックで機能し、一部のC#8機能はまったく機能しません。説明が非常に複雑です。私たちは積極的にそれをブロックしないので、それをナビゲートできるエキスパートユーザーがそれを行うことができます。このサポートされていないミックス&マッチを広く使用することはお勧めしません。

(ヤンコタス)

あなたのように理解し、問題を回避する人は、C#8を自由に使用できます。重要なのは、すべての言語機能が下位レベルのターゲットで機能するわけではないということです。

(イモランドウェルス)


Visual Studio 2019

Visual Studio 2019バージョン16.3のRTMバージョンに大きな変更がありました-C#8.0の起動バージョン:言語選択ドロップダウンが無効になりました:

ここに画像の説明を入力してください

これに対するマイクロソフトの根拠は次のとおりです。

今後、...各フレームワークの各バージョンには、サポートされるデフォルトのバージョンが1つあり、任意のバージョンはサポートされません。このサポートの変更を反映するために、このコミットは言語バージョンのコンボボックスを永続的に無効にし、変更を説明するドキュメントへのリンクを追加します。

開くドキュメントはC#言語のバージョン管理です。これは、C#8.0を.NET Core 3.xのデフォルト言語としてのみ示しています。また、各フレームワークの各バージョンには、今後、サポートされるデフォルトのバージョンが1つあり、フレームワークに依存しない言語に依存できなくなることも確認されています。

.csprojファイルを編集して、.NET Frameworkプロジェクトの言語バージョンを8に強制することもできます。


買い手責任負担

C#8 / .NET Frameworkの組み合わせは、Microsoftによって正式にサポートされていません。彼らは、専門家のためだけのものだと彼らは言う。


3
これにより、標準2.1以外のC#8機能を使用できる場合に発生する混乱が解消されます-github.com/dotnet/corefx/issues/40039
Ben Hall

2
より複雑なnull可能なユースケースを設計するために必要な新しいnull可能な属性(docs.microsoft.com/en-us/dotnet/csharp/nullable-attributes)は、.NET Core 3.0およびに同梱されているSystem.Runtime.dllでのみ使用できます。 NET標準2.1。これにより、null可能\ C#8.0が、NET Framework 4.8と互換性が
なくなります

3
@BenHall私はあなたの問題からいくつかの要点を追加しました-問題を提起し、ここに投稿していただきありがとうございます。なんらかの間違いがある場合は、お気軽に編集してください。
スティーブンケネディ

3
で指定されたときのVisual Studio 2019 IntelliSenseがNULL可能参照型をサポートしていません<Nullable>enable</Nullable>csproj#nullable enableディレクティブを使用すると機能するようです。次も参照してください:github.com/dotnet/project-system/issues/5551
Bouke

3
@odalet C#8をターゲットとし、ポリフィルを必要としない基本機能(既に実行している)を使用し、ポリフィルを使用している(それらを必要としない)しかし、私ができる最善のアドバイスは、疑わしい場合は実行しないでください。少なくとも、あなたの仕事がそれに依存している場合は実行しないでください。
スティーブンケネディ

34

このブログエントリによると、言語は実際にフレームワークに関連付けられています。

つまり、これらの機能を使用するために必要な型は、.NET Framework 4.8では使用できません。同様に、デフォルトのインターフェイスメンバーの実装は、新しいランタイム拡張機能に依存しており、.NETランタイム4.8でもそれらを作成しません。

このため、C#8.0の使用は、.NET Standard 2.1を実装するプラットフォームでのみサポートされています。ランタイムを安定した状態に保つ必要があるため、10年以上にわたって新しい言語機能を実装することができませんでした。現代のランタイムのサイドバイサイドとオープンソースの性質により、責任を持ってそれらを再び進化させ、それを念頭に置いて言語設計を行うことができると感じています。スコットは、.NET Core 3.0および.NET Framework 4.8に関するアップデートで、.NET Frameworkは安定性と信頼性に焦点を当てるのではなく、将来的に革新が少なくなると説明しています。それを考えると、一部の言語機能を見逃した方が、誰もそれらを入手できないよりはましだと思います。


3
Stephen Kennedyによる他の回答の詳細。実際、.NET Frameworkを対象とする場合、C#8.0の実質的なサブセットを機能させるのは簡単です。しかし、C#8.0の一部では、Microsoftが「古い」.NET Framework用に行う予定のないランタイムの変更が必要です。また、言語バージョンと.NETバージョンをより密接に結び付けているようです。
Jeppe Stig Nielsen

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.