У налаштуваннях Visual Studio 2019 Advanced Build C # 8, здається, не доступний для проекту .NET Framework, лише (як на малюнку нижче) для .NET Core 3.0 проекту:
Чи підтримує C # 8 .NET Framework?
У налаштуваннях Visual Studio 2019 Advanced Build 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 - Робота з непідтримуваними речами .
Наступні 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. Справа в тому, що не всі мовні функції працюватимуть на цілях нижчого рівня.
(Іммо Ландверт)
У 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. Це, кажуть, лише для експертів.
<Nullable>enable</Nullable>
в csproj
. Здається, це працює при використанні #nullable enable
директив. Дивіться також: github.com/dotnet/project-system/isissue/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 #