В настройках расширенной сборки Visual Studio 2019 C # 8 недоступен для проекта .NET Framework, только (как показано на рисунке ниже) для проекта .NET Core 3.0:
Поддерживает ли C # 8 .NET Framework?
В настройках расширенной сборки Visual Studio 2019 C # 8 недоступен для проекта .NET Framework, только (как показано на рисунке ниже) для проекта .NET Core 3.0:
Поддерживает ли C # 8 .NET Framework?
Ответы:
Да, C # 8 можно использовать с .NET Framework и другими целями старше .NET Core 3.0 / .NET Standard 2.1 в Visual Studio 2019 (или более старых версиях Visual Studio, если вы устанавливаете пакет Nuget ).
Языковая версия должна быть установлена 8.0
в файле csproj.
Большинство - но не все - функции доступны в зависимости от целевой платформы.
Следующие функции предназначены только для изменения синтаксиса; они работают вне зависимости от фреймворка:
Для этого требуются новые типы, которых нет в .NET Framework. Их можно использовать только вместе с пакетами Nuget "polyfill" или файлами кода:
Члены интерфейса по умолчанию не компилируются под .NET Framework и никогда не будут работать, потому что они требуют изменений среды выполнения в среде CLR. .NET CLR теперь заморожен, поскольку .NET Core теперь является шагом вперед.
Для получения дополнительной информации о том, что работает, а что нет, и о возможных полифилах, см. Статью Стюарта Ланга C # 8.0 и .NET Standard 2.0 - Doing Unsupported Things .
Следующий проект C #, ориентированный на .NET Framework 4.8 и использующий ссылочные типы C # 8, допускающие значение NULL, компилируется в 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; }
}
}
Затем я попробовал проект WinForms .NET Framework 4.5.2, используя устаревший .csproj
формат, и добавил то же свойство ссылочного типа, допускающее значение NULL. Я изменил тип языка в диалоговом окне настроек Visual Studio Advanced Build (отключен в 16.3) на latest
и сохранил проект. Конечно, в этой точке он не строится. Я открыл файл проекта в текстовом редакторе и в конфигурации сборки изменил latest
его preview
на PropertyGroup
:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>preview</LangVersion>
Затем я включил поддержку ссылочных типов, допускающих значение NULL, добавив <Nullable>enable</Nullable>
к основному PropertyGroup
:
<PropertyGroup>
<Nullable>enable</Nullable>
Я перезагружаю проект, и он строится.
Когда этот ответ был впервые написан, C # 8 находился на стадии предварительной версии, и потребовалось много детективной работы. Я оставляю эту информацию здесь для потомков. Не стесняйтесь пропустить это, если вам не нужно знать все кровавые подробности.
Язык C # исторически был в основном нейтральным к фреймворку, т. Е. Способным компилировать старые версии Framework, хотя для некоторых функций требовались новые типы или поддержка среды 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. Эта функция требовала новых типов - ValueTuple
структур, которые не были доступны в версиях NET Framework ниже 4.7 или .NET Standard старше 2.0. Однако C # 7 все еще можно было использовать в более старых версиях .NET либо без кортежей значений, либо с ними, установив пакет Nuget System.ValueTuple . 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.
Началось расследование! -
У Джона Скита есть готовая к работе альфа-версия Noda-Time с использованием C # 8, предназначенная только для .NET Standard 2.0. Он явно ожидает, что C # 8 / .NET Standard 2.0 будет поддерживать все платформы семейства .NET. (См. Также сообщение в блоге Джона «Первые шаги со ссылочными типами, допускающими значение NULL» ).
Сотрудники Microsoft обсуждали пользовательский интерфейс Visual Studio для ссылочных типов C # 8, допускающих значение NULL, на GitHub , и заявлено, что они намерены поддерживать устаревший csproj
формат (формат SDK до .NET Core csproj
). Это очень убедительный признак того, что C # 8 можно будет использовать с .NET Framework. [Я подозреваю, что они откажутся от этого теперь, когда раскрывающийся список языковых версий Visual Studio 2019 отключен, а .NET привязан к C # 7.3]
Вскоре после известного сообщения в блоге в ветке 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 (диапазоны, индексы, асинхронные итераторы, асинхронное удаление).
Виктор Деркс прокомментировал: « Новые атрибуты, допускающие значение NULL, необходимые для разработки более сложных вариантов использования, допускающих значение NULL, доступны только в System.Runtime.dll, который поставляется с .NET Core 3.0 и .NET Standard 2.1 ... [и] несовместим с .NET Framework 4.8 "
Тем не менее, Immo Landwerth прокомментировал, что «подавляющему большинству наших API не требуются какие-либо настраиваемые атрибуты, так как типы являются либо полностью универсальными, либо не имеют значения NULL» в статье « Попробовать ссылочные типы, допускающие значение NULL».
Бен Холл поднял вопрос о доступности атрибутов, допускающих значение NULL, вне Core 3.0 на GitHub, при этом следует отметить следующие комментарии сотрудников Microsoft:
C # 8 будет полностью поддерживаться только в .net core 3.0 и .net standard 2.1. Если вы вручную отредактируете файл проекта для использования C # 8 с .net core 2.1, вы окажетесь на неподдерживаемой территории. Некоторые функции C # 8 будут работать хорошо, некоторые функции C # 8 будут работать не слишком хорошо (например, низкая производительность), некоторые функции C # 8 будут работать с дополнительными хитростями, а некоторые функции C # 8 не будут работать вообще. Очень сложно объяснить. Мы не блокируем его активно, поэтому это могут сделать опытные пользователи, которые могут перемещаться по нему. Я бы не рекомендовал широко использовать это неподдерживаемое сочетание и совпадение.
(Ян Котас)
Такие люди, как вы, которые хотят понять - и обойти их - могут свободно использовать C # 8. Дело в том, что не все языковые функции будут работать с целями нижнего уровня.
(Иммо Ландверт)
В RTM-версии Visual Studio 2019 версии 16.3 произошло серьезное изменение - в стартовой версии для C # 8.0: раскрывающийся список выбора языка отключен:
Обоснование этого Microsoft :
В дальнейшем ... каждая версия каждой платформы будет иметь одну поддерживаемую версию по умолчанию, и мы не будем поддерживать произвольные версии. Чтобы отразить это изменение в поддержке, эта фиксация навсегда отключает поле со списком языковой версии и добавляет ссылку на документ, объясняющий изменение.
Откроется документ с версией на языке C # . Здесь C # 8.0 указан как язык по умолчанию ТОЛЬКО для .NET Core 3.x. Это также подтверждает, что каждая версия каждой платформы в будущем будет иметь единственную поддерживаемую версию по умолчанию и что на агностицизм языка больше нельзя полагаться.
Языковая версия все еще может быть установлена на 8 для проектов .NET Framework, отредактировав файл .csproj.
Комбинация C # 8 / .NET Framework официально не поддерживается Microsoft. Они говорят, что это только для экспертов.
<Nullable>enable</Nullable>
в csproj
. Вроде работает при использовании #nullable enable
директив. Смотрите также: github.com/dotnet/project-system/issues/5551
Согласно этой записи в блоге, язык действительно привязан к фреймворку:
Это означает, что типы, необходимые для использования этих функций, не будут доступны в .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 будет меньше инноваций в будущем, вместо этого сосредоточившись на стабильности и надежности. Учитывая это, мы считаем, что лучше упустить некоторые языковые функции, чем никому их получить.
C # 8.0 (и выше) поддерживается только в .NET Core 3.x и более новых версиях. Многие из новейших функций требуют функций библиотеки и среды выполнения, представленных в .NET Core 3.x: управление версиями языка C #