Oui, C # 8 peut être utilisé avec .NET Framework et d'autres cibles antérieures à .NET Core 3.0 / .NET Standard 2.1 dans Visual Studio 2019 (ou des versions antérieures de Visual Studio si vous installez un package Nuget ).
La version linguistique doit être définie 8.0
dans le fichier csproj.
La plupart des fonctionnalités - mais pas toutes - sont disponibles quel que soit le cadre ciblé.
Fonctionnalités qui fonctionnent
Les fonctionnalités suivantes sont des modifications de syntaxe uniquement; ils fonctionnent quel que soit le cadre:
Fonctionnalités qui peuvent être mises en œuvre
Ceux-ci nécessitent de nouveaux types qui ne sont pas dans le .NET Framework. Ils ne peuvent être utilisés qu'avec des packages Nuget "polyfill" ou des fichiers de code:
Membres de l'interface par défaut - ne fonctionnent pas
Les membres de l'interface par défaut ne compileront pas sous .NET Framework et ne fonctionneront jamais car ils nécessitent des modifications d'exécution dans le CLR. Le .NET CLR est maintenant figé car .NET Core est désormais la voie à suivre.
Pour plus d'informations sur ce qui fonctionne et ce qui ne fonctionne pas, et sur les polyfills possibles, consultez l'article de Stuart Lang, C # 8.0 et .NET Standard 2.0 - Faire des choses non prises en charge .
Code
Le projet C # suivant ciblant .NET Framework 4.8 et utilisant des types de référence Nullable C # 8 se compile dans Visual Studio 16.2.0. Je l'ai créé en choisissant le modèle de bibliothèque de classes standard .NET, puis en le modifiant pour cibler .NET Framework à la place:
.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; }
}
}
J'ai ensuite essayé un projet WinForms .NET Framework 4.5.2, en utilisant un .csproj
format hérité , et j'ai ajouté la même propriété de type de référence nullable. J'ai changé le type de langue dans la boîte de dialogue des paramètres de Visual Studio Advanced Build (désactivée dans 16.3) latest
et enregistré le projet. Bien sûr, à ce stade, il ne se construit pas. J'ai ouvert le fichier de projet dans un éditeur de texte et changé latest
en preview
dans la configuration de construction PropertyGroup
:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>preview</LangVersion>
J'ai ensuite activé la prise en charge des types de référence Nullable en ajoutant <Nullable>enable</Nullable>
au principal PropertyGroup
:
<PropertyGroup>
<Nullable>enable</Nullable>
J'ai rechargé le projet, et il se construit.
Les détails sanglants
Lorsque cette réponse a été écrite pour la première fois, C # 8 était en avant-première et beaucoup de travail de détective a été impliqué. Je laisse cette information ici pour la postérité. N'hésitez pas à l'ignorer si vous n'avez pas besoin de connaître tous les détails sanglants.
Le langage C # a toujours été essentiellement indépendant du framework - c'est-à-dire capable de compiler les anciennes versions du Framework - bien que certaines fonctionnalités aient nécessité de nouveaux types ou la prise en charge de CLR.
La plupart des passionnés de C # auront lu l'entrée de blog Building C # 8.0 de Mads Torgersen, qui explique que certaines fonctionnalités de C # 8 ont des dépendances de plate-forme:
Les flux, indexeurs et plages asynchrones reposent tous sur de nouveaux types de framework qui feront partie de .NET Standard 2.1 ... .NET Core 3.0 ainsi que Xamarin, Unity et Mono implémenteront tous .NET Standard 2.1, mais .NET Framework 4.8 ne pas. Cela signifie que les types requis pour utiliser ces fonctionnalités ne seront pas disponibles sur .NET Framework 4.8.
Cela ressemble un peu aux tuples de valeur qui ont été introduits dans C # 7. Cette fonctionnalité nécessitait de nouveaux types - les ValueTuple
structures - qui n'étaient pas disponibles dans les versions NET Framework inférieures à 4.7 ou .NET Standard antérieures à 2.0. Cependant , C # 7 peut toujours être utilisé dans les anciennes versions de .NET, soit sans tuples de valeur, soit avec eux en installant le package System.ValueTuple Nuget . Visual Studio l'a compris et tout allait bien dans le monde.
Cependant, Mads a également écrit:
Pour cette raison, l'utilisation de C # 8.0 n'est prise en charge que sur les plates-formes qui implémentent .NET Standard 2.1.
... qui, s'il était vrai, aurait exclu l'utilisation de C # 8 avec n'importe quelle version de .NET Framework, et même dans les bibliothèques .NET Standard 2.0 que nous avons récemment été encouragés à utiliser comme cible de base pour le code de bibliothèque. Vous ne pourriez même pas l'utiliser avec les versions .NET Core antérieures à 3.0 car elles ne prennent également en charge que .NET Standard 2.0.
L'enquête était ouverte! -
Jon Skeet a une version alpha de Noda-Time utilisant C # 8 prête à l'emploi qui cible uniquement .NET Standard 2.0. Il s'attend clairement à ce que C # 8 / .NET Standard 2.0 prenne en charge tous les frameworks de la famille .NET. (Voir aussi l'article de blog de Jon "Premiers pas avec les types de référence Nullable" ).
Les employés de Microsoft ont discuté de l'interface utilisateur de Visual Studio pour les types de référence nullable C # 8 sur GitHub , et il est indiqué qu'ils ont l'intention de prendre en charge l'héritage csproj
(format pré- .NET Core SDK csproj
). C'est une indication très forte que C # 8 sera utilisable avec le .NET Framework. [Je soupçonne qu'ils vont revenir en arrière maintenant que la liste déroulante de la version linguistique de Visual Studio 2019 a été désactivée et que .NET a été lié à C # 7.3]
Peu de temps après le célèbre article de blog, un fil de discussion GitHub a discuté du support multiplateforme. Un point important qui a émergé était que .NET Standard 2.1 inclura un marqueur indiquant que les implémentations par défaut des interfaces sont prises en charge - la fonctionnalité nécessite une modification CLR qui ne sera jamais disponible pour le .NET Framework. Voici l'essentiel, de Immo Landwerth, responsable de programme de l'équipe .NET chez Microsoft:
Les compilateurs (tels que C #) doivent utiliser la présence de ce champ pour décider d'autoriser ou non les implémentations d'interface par défaut. Si le champ est présent, le runtime devrait pouvoir charger et exécuter le code résultant.
Tout cela indiquait que "C # 8.0 n'est pris en charge que sur les plates-formes qui implémentent .NET Standard 2.1" étant une simplification excessive, et que C # 8 prendra en charge le .NET Framework mais, comme il y a tellement d'incertitude, j'ai demandé sur GitHub et HaloFour a répondu:
IIRC, la seule fonctionnalité qui n'apparaîtra certainement pas sur .NET Framework est DIM (méthodes d'interface par défaut) car cela nécessite des modifications d'exécution. Les autres fonctionnalités sont gérées par la forme des classes qui pourraient ne jamais être ajoutées au .NET Framework mais qui peuvent être polyfilled via votre propre code ou NuGet (plages, index, itérateurs asynchrones, élimination asynchrone).
Victor Derks a commenté que «Les nouveaux attributs Nullable requis pour concevoir les cas d'utilisation Nullable plus complexes sont uniquement disponibles dans System.Runtime.dll qui est livré avec .NET Core 3.0 et .NET Standard 2.1 ... [et] incompatible avec .NET Framework 4,8 "
Cependant, Immo Landwerth a commenté que "La grande majorité de nos API n'avaient pas besoin d'attributs personnalisés car les types sont soit entièrement génériques ou non nuls" dans l'article Essayer les types de référence Nullable
Ben Hall a soulevé le problème de la disponibilité des attributs nullables en dehors de Core 3.0 sur GitHub, les commentaires suivants des employés de Microsoft étant à noter:
C # 8 sera entièrement pris en charge sur .net core 3.0 et .net standard 2.1 uniquement. Si vous modifiez manuellement le fichier projet pour utiliser C # 8 avec .net core 2.1, vous vous trouvez dans un territoire non pris en charge. Certaines fonctionnalités C # 8 fonctionneront bien, certaines fonctionnalités C # 8 ne fonctionneront pas très bien (par exemple, de mauvaises performances), certaines fonctionnalités C # 8 fonctionneront avec des hacks supplémentaires et certaines fonctionnalités C # 8 ne fonctionneront pas du tout. Très complexe à expliquer. Nous ne le bloquons pas activement afin que les utilisateurs experts qui peuvent y naviguer puissent le faire. Je ne recommanderais pas que ce mix & match non pris en charge soit largement utilisé.
(Jan Kotas)
Les gens comme vous qui sont prêts à les comprendre - et à les contourner - sont libres d'utiliser C # 8. Le fait est que toutes les fonctionnalités du langage ne fonctionneront pas sur des cibles de bas niveau.
(Immo Landwerth)
Visual Studio 2019
Il y a eu un changement majeur dans la version RTM de Visual Studio 2019 version 16.3 - la version de lancement pour C # 8.0: la liste déroulante de sélection de langue a été désactivée:
La justification de Microsoft à cet égard est:
À l'avenir, ... chaque version de chaque framework aura une seule version prise en charge et par défaut, et nous ne prendrons pas en charge les versions arbitraires. Pour refléter ce changement de prise en charge, ce commit désactive définitivement la liste déroulante de la version linguistique et ajoute un lien vers un document expliquant le changement.
Le document qui s'ouvre est le contrôle de version en langage C # . Cela répertorie C # 8.0 comme langue par défaut pour .NET Core 3.x UNIQUEMENT. Il confirme également que chaque version de chaque framework aura, à l'avenir, une seule version prise en charge et par défaut et que l'agnosticisme du framework ne pourra plus être invoqué.
La version linguistique peut toujours être forcée à 8 pour les projets .NET Framework en modifiant le fichier .csproj.
Caveat emptor
La combinaison C # 8 / .NET Framework n'est pas officiellement prise en charge par Microsoft. C'est, disent-ils, réservé aux experts.
<Nullable>enable</Nullable>
lecsproj
. Cela semble fonctionner lors de l'utilisation de#nullable enable
directives. Voir aussi: github.com/dotnet/project-system/issues/5551Selon cette entrée de blog, la langue est en effet liée au cadre:
la source
la source