web-dev-qa-db-ja.com

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

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

enter image description here

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

96
James Harcourt

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

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

すべてではありませんが、ほとんどの機能は、対象となるフレームワークに関係なく使用できます。


機能する機能

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

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

これらには、.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に変更して、プロジェクトを保存しました。もちろん、この時点ではビルドされません。テキストエディターでプロジェクトファイルを開き、ビルド構成latestpreviewPropertyGroupに変更しました。

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

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

<PropertyGroup>
   <Nullable>enable</Nullable>

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


悲惨な詳細

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

C#言語は歴史的に 大部分はフレームワークニュートラル です。つまり、古いバージョンのフレームワークをコンパイルできます-一部の機能では新しいタイプまたはCLRサポートが必要です。

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

非同期ストリーム、インデクサー、範囲はすべて、.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 のように見えます。この機能には、4.7以降のNET Frameworkバージョンでは利用できない新しい型-ValueTuple構造体が必要でした。 2.0より古いNET Standard。 ただし、C#7は以前のバージョンの.NETでも、値タプルなしで、または System.ValueTupleをインストールすることで使用できますNugetパッケージ 。 Visual Studioはこれを理解し、すべてが世界的に順調でした。

しかし、マッズはまた書いている:

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

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

調査が始まりました! -

  • Jon Skeetには、C#8 ready to go を使用するNoda-Timeのアルファバージョンがあり、.NET Standard 2.0のみを対象としています。彼は明らかに、C#8/.NET Standard 2.0が.NETファミリのすべてのフレームワークをサポートすることを期待しています。 (Jonのブログ投稿 "nullable reference typesを使用した最初のステップ" も参照)。

  • Microsoftの従業員はVisual Studio UI for C#8 nullable reference types on GitHub について話し合っており、レガシーcsproj(pre.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 は、「より複雑なnull可能なユースケースを設計するために必要な new nullableの属性 は、.NETに付属するSystem.Runtime.dllでのみ利用可能であるとコメントしました。 Core 3.0および.NET Standard 2.1 ... [および] .NET Framework 4.8と互換性がない

  • ただし、Immo Landwerth commented の記事 Try outで、「ほとんどのAPIは、タイプが完全に汎用的であるかnullでないため、カスタム属性を必要としませんでした」 null可能参照タイプ

  • 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

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

enter image description here

Microsoftの rationale これは次のとおりです。

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

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

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


買い手責任負担

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

163
Stephen Kennedy

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

つまり、これらの機能を使用するために必要なタイプは、.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は安定性と信頼性に重​​点を置くのではなく、将来的に革新が少なくなると説明しています。それを踏まえると、一部の言語機能を見逃した方が、誰もそれらを入手できないよりはましだと思います。

31
user1781290

C#8.0以降は、.NET Core 3.x以降のバージョンでのみサポートされています。最新の機能の多くは、.NET Core 3.xで導入されたライブラリおよびランタイム機能を必要とします。 C#言語のバージョン管理

0