Поддерживает ли C # 8 .NET Framework? - PullRequest
3 голосов
/ 18 июня 2019

В настройках Visual Studio 2019 Advanced Build C # 8, по-видимому, недоступен для проекта .NET Framework, только (как на рисунке ниже) для проекта .NET Core 3.0:

enter image description here

Поддерживает ли C # 8 .NET Framework?

Ответы [ 2 ]

7 голосов
/ 18 июня 2019

Согласно этой записи в блоге язык действительно связан с фреймворком:

Это означает, что типы, необходимые для использования этих функций, не будут доступны в .NET Framework 4.8. Аналогично, реализации элементов интерфейса по умолчанию полагаются на новые усовершенствования среды выполнения, и мы не будем делать их в .NET Runtime 4.8.

По этой причине использование C # 8.0 поддерживается только на платформах, которые реализуют .NET Standard 2.1. Необходимость сохранения стабильности среды выполнения мешала нам внедрять новые языковые функции в течение более десяти лет. Учитывая параллельную и открытую природу современных сред выполнения, мы чувствуем, что мы можем ответственно развивать их снова и делать дизайн языка с учетом этого. Скотт объяснил в своем обновлении .NET Core 3.0 и .NET Framework 4.8, что в будущем в .NET Framework будет меньше инноваций, вместо этого он сосредоточится на стабильности и надежности. Учитывая это, мы считаем, что для него лучше упустить некоторые языковые функции, чем никто их не получит.

5 голосов
/ 13 июля 2019

Это довольно длинный ответ, и информация в этом документе может быть изменена, так как C # 8 и инструменты Visual Studio все еще находятся в предварительном просмотре. Я постараюсь держать ответ в курсе, если что-то изменится.

Короче говоря, на момент написания статьи C # 8 можно использовать с .NET Framework в Visual Studio 2019 Preview, и я ожидаю, что так будет и впредь, но я бы не поставил на это ферму. Не все функции будут доступны - в частности .NET Framework никогда не будет поддерживать методы интерфейса по умолчанию.

Пожалуйста, перейдите к концу этого ответа, если вы просто хотите увидеть код.


Язык C # исторически в основном не зависел от фреймворка - т.е. мог компилировать более старые версии Framework - хотя некоторые функции требовали поддержки новых типов или CLR. На этот раз .NET Framework не получит никаких новых типов, если они не отображаются в виде пакетов Nuget.

Я полагаю, что большинство энтузиастов C # уже прочитали запись в блоге Building C # 8.0 от Mads Torgersen, которая объясняет, что некоторые функции 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. Для этой функции требовались новые типы - ValueTuple структуры - которые не были доступны в версиях NET Framework ниже 4.7 или .NET Standard старше 2.0. Однако , C # 7 все еще можно использовать в более старых версиях .NET, без кортежей значений или вместе с ними, установив пакет System.ValueTuple Nuget . Visual Studio это поняла, и с миром все было в порядке.

Я ожидал, что C # 8 будет работать таким же образом - нацеливаться на любую среду, в которой вы нуждаетесь, но некоторые функции не будут доступны, и Visual Studio поможет вам убедиться, что вы не пишете код, который может ' т компилировать. Однако, с тревогой, Мэдс также писал:

По этой причине использование C # 8.0 поддерживается только на платформах, которые реализуют .NET Standard 2.1.

... что исключало бы использование C # 8 с любой версией .NET Framework и даже в библиотеках .NET Standard 2.0, которые только недавно нам предложили использовать в качестве базовой цели для код библиотеки. Вы даже не сможете использовать его с версиями .NET Core старше 3.0, поскольку они также поддерживают только .NET Standard 2.0.

Я много копался, поскольку это утверждение не соответствовало моему собственному опыту использования C # 8 и обнуляемых ссылочных типов в многочисленных проектах .NET Standard 2.0 (и помните, .NET Standard это просто список API; если проект .NET 4.8 использует библиотеку .NET Standard 2.0, код будет выполняться в .NET CLR / с использованием API .NET Framework).

Вот некоторые вещи, которые я нашел:

  • У Джона Скита есть альфа-версия Noda-Time, использующая C # 8 готовая к работе , предназначенная только для .NET Standard 2.0. Он явно ожидает, что C # 8 / .NET Standard 2.0 будет поддерживать все платформы семейства .NET. (См. Также сообщение Джона в блоге "Первые шаги с типами ссылок, которые могут быть недействительными" ).

  • Сотрудники Microsoft обсуждали пользовательский интерфейс Visual Studio для обнуляемых ссылочных типов C # 8 на GitHub , и заявлено, что они намерены поддерживать устаревшую csproj (до .NET Core Формат SDK csproj). Это очень убедительный признак того, что C # 8 будет использоваться с .NET Framework.

  • Вскоре после известной публикации в блоге GitHub-ветка обсуждала межплатформенную поддержку. Важным моментом, который возник, было то, что .NET Standard 2.1 будет включать маркер, обозначающий, что поддерживаются реализации интерфейсов по умолчанию - функция требует изменения CLR, которое никогда не будет доступно .NET Framework. Вот важный момент, от Иммо Ландверта, менеджера программ в команде .NET в Microsoft:

    Компиляторы (такие как C #), как ожидается, будут использовать наличие этого поля, чтобы решить, разрешать ли реализации интерфейса по умолчанию. Если поле присутствует, ожидается, что среда выполнения сможет загружать и выполнять полученный код.

  • Все это указывает на то, что «C # 8.0 поддерживается только на платформах, которые реализуют .NET Standard 2.1», что является чрезмерным упрощением, и что C # 8 будет поддерживать .NET Framework , но, как есть так много неопределенности, я спросил на GitHub . Пока у меня есть один ответ от HaloFour:

    IIRC, единственная функция, которая определенно не появится в .NET Framework, - это DIM (методы интерфейса по умолчанию), поскольку она требует изменений во время выполнения. Другие функции определяются формой классов, которые никогда не могут быть добавлены в .NET Framework, но могут быть заполнены с помощью собственного кода или NuGet (диапазоны, индексы, асинхронные итераторы, асинхронное удаление).


Эссе закончено, давайте посмотрим на некоторый код. Следующий проект C #, нацеленный на .NET 4.8 и использующий ссылочные типы C # 8, компилируется в Visual Studio 16.2.0 Preview 3. Я создал его, выбрав шаблон .NET Standard Class Library и затем вместо этого отредактировав его для целевого .NET:

.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; }
    }
}

Затем я попробовал WinNET-проект .NET 4.5.2, используя устаревший формат .csproj, и добавил то же свойство ссылочного типа, допускающее обнуляемость. Я изменил тип языка в диалоговом окне настроек Visual Studio Advanced Build на latest и сохранил проект. Конечно, как этот пункт он не строит. Я открыл файл проекта в текстовом редакторе и изменил latest на preview в конфигурации сборки PropertyGroup:

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

Затем я включил поддержку необнуляемых ссылочных типов, добавив <Nullable>enable</Nullable> к основному PropertyGroup:

<PropertyGroup>
   <Nullable>enable</Nullable>

Я перезагрузил проект, и он собирается.

Поэтому я могу подтвердить, что по крайней мере на момент написания C # 8 поддерживает .NET Framework, но инструментальные средства Visual Studio не догнали. Microsoft работает над инструментальными средствами, в том числе для устаревших csproj формат файлов.

...