Поддерживает ли C# 8.NET Framework?
4 ответа
Согласно этой записи в блоге язык действительно привязан к фреймворку:
Это означает, что типы, необходимые для использования этих функций, не будут доступны в.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 и инструменты Visual Studio все еще находятся в предварительном просмотре. Я постараюсь держать ответ в курсе, если что-то изменится.
Коротко говоря, во время написания статьи C# 8 можно использовать с.NET Framework в Visual Studio 2019 Preview. Не все функции будут доступны - в частности.NET Framework никогда не будет поддерживать методы интерфейса по умолчанию. По сути, Microsoft не блокирует использование C# 8, но, похоже, заявляет, что он не поддерживается и предназначен только для экспертов.
Пожалуйста, перейдите к концу этого ответа, если вы просто хотите увидеть код.
Язык 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, либо без кортежей значений, либо с ними, установив пакет Nuget System.ValueTuple. 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 (диапазоны, индексы, асинхронные итераторы, асинхронное удаление).
Victor Derks отметил, что " Новые атрибуты, допускающие обнуляемость, необходимые для разработки более сложных случаев использования, допускающих обнуляемость, доступны только в System.Runtime.dll, которая поставляется с.NET Core 3.0 и.NET Standard 2.1... [и] несовместима с.NET Framework 4,8"
Тем не менее, Immo Landwerth отметил, что "подавляющему большинству наших API не нужны никакие пользовательские атрибуты, так как типы являются либо полностью универсальными, либо ненулевыми" в статье " Испытайте допустимые ссылочные типы"
Ben Hall поднял вопрос " Доступность атрибутов, допускающих значение 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#. Дело в том, что не все языковые функции будут работать на нижних уровнях.
(Иммо Ландверт)
Эссе закончено, давайте посмотрим на некоторый код. Следующий проект 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; }
}
}
Затем я попробовал.NET 4.5.2 WinForms проект, используя устаревшую .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 и указано, требуют ли они изменений во время выполнения или являются просто изменениями компилятора:
- Члены только для чтения (компилятор)
- Методы интерфейса по умолчанию (время выполнения)
- улучшения сопоставления с образцом (компилятор)
- переключать выражения
- Шаблон свойства
- Шаблоны кортежей
- Позиционные модели
- Использование объявлений (компилятор)
- Статические локальные функции (компилятор)
- Одноразовые ссылочные структуры (компилятор)
- Ссылочные типы, допускающие значение NULL (компилятор с оговоркой: анализ, допускающий значение NULL, частично опирается на типы, которые не будут существовать)
- Асинхронные потоки (компилятор, необходимо установить Microsoft.Bcl.AsyncInterfaces)
- Индексы и диапазоны (компилятор, но требуется система классов.Range плюс другие классы )
- Назначение с нулевым объединением (компилятор)
- Неуправляемые сконструированные типы (компилятор)
- Stackalloc во вложенных выражениях (компилятор)
- Улучшение интерполированной дословной строки (компилятор, @$ совпадает с $@)
C# 8.0 (и выше) поддерживается только в.NET Core 3.x и более новых версиях. Многие из новейших функций требуют функций библиотеки и среды выполнения, представленных в.NET Core 3.x: управление версиями языка C#