Чи підтримує C # 8 .NET Framework?


131

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

введіть тут опис зображення

Чи підтримує C # 8 .NET Framework?

Відповіді:


239

Так, 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 - Робота з непідтримуваними речами .


Код

Наступні C # -проекти, орієнтовані на .NET Framework 4.8 та використання компресійних посилальних типів C # 8, компілюються у Visual Studio 16.2.0. Я створив його, вибравши шаблон бібліотеки .NET Standard Class, а потім відредагувавши його, щоб націлити на .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; }
    }
}

Потім я спробував проект .NET Framework 4.5.2 WinForms, використовуючи застарілий .csprojформат, і додав ту саму властивість нульового довідкового типу. Я змінив тип мови в діалоговому вікні налаштувань розширеної збірки Visual Studio (відключений в 16.3) latestі зберег проект. Звичайно, оскільки цей момент не розвивається. Я відкрив файл проекту в текстовому редакторі і змінений , latestщоб previewв конфігурації збірки PropertyGroup:

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

Потім я включив підтримку зведених типів посилань, додавши <Nullable>enable</Nullable>до основного PropertyGroup:

<PropertyGroup>
   <Nullable>enable</Nullable>

Я перезавантажив проект, і він будується.


Деталі горі

Коли ця відповідь була вперше написана, C # 8 був у попередньому перегляді, і було задіяно багато детективних робіт. Я залишаю цю інформацію тут для нащадків. Не соромтеся пропустити це, якщо вам не потрібно знати всі деталі горі.

Мова C # історично здебільшого була нейтральною для фреймворку - тобто могла компілювати старіші версії Framework - хоча деякі функції вимагали нових типів або підтримки CLR.

Більшість ентузіастів C # прочитають запис про блог Макет Торгерсен у будівлі 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.

Це трохи схоже на значення Tuples , представлені в C # 7. Ця функція вимагала нових типів - ValueTupleструктур - які не були доступні у версіях NET Framework нижче 4,7 або .NET Standard старше 2,0. Однак C # 7 все ще може використовуватися в старих версіях .NET, або без кортезів значень, або з ними, встановивши пакет System.ValueTuple Nuget . 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. (Див. Також допис у блозі Джона "Перші кроки із змінними типами посилань" ).

  • Співробітники Microsoft обговорювали інтерфейс Visual Studio UI для змінних типів посилань C # 8 на GitHub , і було заявлено, що вони мають намір підтримати спадщину csproj(формат попереднього.NET Core SDK 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 (діапазони, індекси, ітератори асинхронізації, розпорядження асинхронізацією).

  • Віктор Деркс прокоментував, що " Нові атрибути, що змінюються, необхідні для проектування більш складних випадків використання змінних даних, доступні лише в System.Runtime.dll, що постачається з .NET Core 3.0 і .NET Standard 2.1 ... [і], несумісні з .NET Framework 4,8 "

  • Однак Іммо Ландверт зауважив, що "Переважній більшості наших API не потрібні спеціальні атрибути, оскільки типи є повністю загальними або не мають значення" під статтею " Спробуйте нульові посилання".

  • Бен Холл порушив питання про наявність змінних атрибутів за межами Core 3.0 на GitHub, із зазначенням таких коментарів працівників Microsoft:

C # 8 повністю підтримується лише у .net core 3.0 та .net стандарт 2.1. Якщо ви вручну редагуєте файл проекту для використання C # 8 з .net core 2.1, ви перебуваєте на непідтримуваній території. Деякі функції C # 8 будуть працювати добре, деякі функції C # 8 працюватимуть не надто добре (наприклад, низька продуктивність), деякі функції C # 8 працюватимуть із додатковими хаками, а деякі функції C # 8 взагалі не працюватимуть. Дуже складно пояснити. Ми не активно його блокуємо, тому досвідчені користувачі, які можуть переходити по ньому, можуть це робити. Я б не рекомендував широко використовувати цю непідтримувану суміш і відповідність.

(Ян Котас)

Такі люди, як ви, бажаєте зрозуміти - і працювати навколо них - вільно користуватися C № 8. Справа в тому, що не всі мовні функції працюватимуть на цілях нижчого рівня.

(Іммо Ландверт)


Візуальна студія 2019

У RTM-версії Visual Studio 2019 версії 16.3 відбулася значна зміна - запуск версії для C # 8.0: випадання вибору мови було вимкнено:

введіть тут опис зображення

Microsoft обґрунтування цього:

Просуваючись вперед, ... кожна версія кожної рамки матиме одну підтримувану та за замовчуванням версію, і ми не підтримуємо довільні версії. Щоб відобразити цю зміну в підтримці, ця команда назавжди вимикає комбіноване поле мовної версії та додає посилання на документ, що пояснює зміни.

Документ, який відкриється, - це версія мови C # . У цьому списку C # 8.0 вказана мова за замовчуванням для .NET Core 3.x ТОЛЬКО. Він також підтверджує, що кожна версія кожного фреймворку буде, у майбутньому, мати одну підтримувану та за замовчуванням версію і на рамкову агностицизм мови вже не можна покладатися.

Мовна версія все ще може бути змушена використовувати 8 для .NET Framework проектів, редагуючи файл .csproj.


Caveat emptor

Майкрософт офіційно не підтримує комбінацію C # 8 / .NET Framework. Це, кажуть, лише для експертів.


3
Це повинно усунути будь-яку плутанину, що випливає з того, що ми можемо використати деякі функції C # 8 поза стандартом 2.1 - github.com/dotnet/corefx/isissue/40039
Ben Hall

2
Нові атрибути, що змінюються ( docs.microsoft.com/en-us/dotnet/csharp/nullable-attributes ), необхідні для проектування більш складних випадків використання зведених даних, доступні лише в System.Runtime.dll, що постачається з .NET Core 3.0 та. Стандарт NET 2.1. Це робить незмінні \ C # 8.0 несумісними з NET Framework 4.8
Victor Derks

3
@BenHall Я додав кілька записів щодо вашої проблеми - дякую за те, що ви порушили цю проблему та розмістили тут. Будь ласка, не соромтесь відредагувати відповідь, якщо вона є невірною.
Стівен Кеннеді

3
Visual Studio 2019 IntelliSense не підтримує зведені типи посилань, якщо вони визначені <Nullable>enable</Nullable>в csproj. Здається, це працює при використанні #nullable enableдиректив. Дивіться також: github.com/dotnet/project-system/isissue/5551
Bouke

3
@odalet У мене не було б ніяких труднощів, націлених на C # 8 та використання основних функцій, які не потребують поліфілів (вже це роблять), а можливо, і з поліфазовами (вони також не потрібні). Однак найкраща порада, яку я можу бути, це: якщо ви сумніваєтеся, не робіть цього, принаймні ні, якщо від цього залежить ваша робота.
Стівен Кеннеді

34

Відповідно до цього запису в блозі, мова дійсно прив’язана до рамки:

Це означає, що типи, необхідні для використання цих функцій, не будуть доступні в .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 буде бачити менше інновацій у майбутньому, замість цього зосереджуючись на стабільності та надійності. Враховуючи це, ми вважаємо, що краще пропустити деякі мовні особливості, ніж нікому їх отримати.


3
Ще багато деталей в іншій відповіді Стівена Кеннеді. Насправді досить просто змусити значну підмножину роботи C # 8.0 працювати при орієнтації на .NET Framework. Але деякі частини C # 8.0 вимагають змін у режимі виконання, які Microsoft не збирається вносити для "старого" .NET Framework. І вони, здається, більше зв’язують мовну версію та версію .NET.
Джеппе Стіг Нільсен

1

C # 8.0 (і новіші версії) підтримується лише у .NET Core 3.x та новіших версіях. Для багатьох найновіших функцій потрібні функції бібліотеки та часу виконання, введені в .NET Core 3.x: Версія мови C #


3
Ви бачили позначену як правильну відповідь від @stephen kennedy вище?
Джеймс Харкорт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.