Ja, C # 8 kann mit .NET Framework und anderen Zielen verwendet werden, die älter als .NET Core 3.0 / .NET Standard 2.1 in Visual Studio 2019 sind (oder ältere Versionen von Visual Studio, wenn Sie ein Nuget-Paket installieren ).
Die Sprachversion muss 8.0
in der csproj-Datei eingestellt sein.
Die meisten - aber nicht alle - Funktionen sind verfügbar, je nachdem, welches Framework angestrebt wird.
Funktionen, die funktionieren
Die folgenden Funktionen sind nur Syntaxänderungen. Sie arbeiten unabhängig vom Rahmen:
Funktionen, die zum Funktionieren gebracht werden können
Diese erfordern neue Typen, die nicht in .NET Framework enthalten sind. Sie können nur in Verbindung mit "Polyfill" -Nuget-Paketen oder Codedateien verwendet werden:
Standardschnittstellenmitglieder - funktionieren nicht
Standardschnittstellenmitglieder werden unter .NET Framework nicht kompiliert und funktionieren nie, da sie Laufzeitänderungen in der CLR erfordern. Die .NET CLR ist jetzt eingefroren, da .NET Core jetzt der richtige Weg ist.
Weitere Informationen dazu, was funktioniert und was nicht, und zu möglichen Polyfills finden Sie in Stuart Langs Artikel C # 8.0 und .NET Standard 2.0 - Nicht unterstützte Aufgaben .
Code
Das folgende C # -Projekt, das auf .NET Framework 4.8 abzielt und C # 8-nullfähige Referenztypen verwendet, wird in Visual Studio 16.2.0 kompiliert. Ich habe es erstellt, indem ich die .NET Standard Class Library-Vorlage ausgewählt und sie stattdessen so bearbeitet habe, dass sie auf .NET Framework abzielt:
.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; }
}
}
Ich habe dann ein WinForms-Projekt mit .NET Framework 4.5.2 unter Verwendung eines Legacy- .csproj
Formats ausprobiert und dieselbe nullfähige Referenztyp-Eigenschaft hinzugefügt. Ich habe den Sprachtyp im Dialogfeld "Erweiterte Build-Einstellungen für Visual Studio" (in 16.3 deaktiviert) in geändert latest
und das Projekt gespeichert. Natürlich baut es an diesem Punkt nicht auf. Ich öffnete die Projektdatei in einem Texteditor und geändert , latest
um preview
in der Build - Konfiguration PropertyGroup
:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>preview</LangVersion>
Ich habe dann die Unterstützung für nullfähige Referenztypen aktiviert, indem ich Folgendes hinzugefügt <Nullable>enable</Nullable>
habe PropertyGroup
:
<PropertyGroup>
<Nullable>enable</Nullable>
Ich habe das Projekt neu geladen und es wird erstellt.
Die blutigen Details
Als diese Antwort zum ersten Mal geschrieben wurde, war C # 8 in der Vorschau und es war viel Detektivarbeit erforderlich. Ich lasse diese Informationen hier für die Nachwelt. Sie können es gerne überspringen, wenn Sie nicht alle wichtigen Details kennen müssen.
Die C # -Sprache war in der Vergangenheit größtenteils Framework-neutral - dh sie konnte ältere Versionen des Frameworks kompilieren - obwohl für einige Funktionen neue Typen oder CLR-Unterstützung erforderlich waren.
Die meisten C # -Enthusiasten haben den Blogeintrag Building C # 8.0 von Mads Torgersen gelesen , in dem erklärt wird, dass bestimmte Funktionen von C # 8 plattformabhängig sind:
Asynchrone Streams, Indexer und Bereiche basieren alle auf neuen Framework-Typen, die Teil von .NET Standard 2.1 sein werden. .NET Core 3.0 sowie Xamarin, Unity und Mono werden .NET Standard 2.1 implementieren, .NET Framework 4.8 jedoch nicht. Dies bedeutet, dass die zur Verwendung dieser Funktionen erforderlichen Typen in .NET Framework 4.8 nicht verfügbar sind.
Dies ähnelt ein wenig den in C # 7 eingeführten Wertetupeln . Für diese Funktion waren neue Typen erforderlich - die ValueTuple
Strukturen -, die in NET Framework-Versionen unter 4.7 oder .NET Standard älter als 2.0 nicht verfügbar waren. Allerdings , C # 7 könnte noch in älteren Versionen von .NET verwendet werden, entweder ohne Wertetupeln oder mit ihnen durch die Installation System.ValueTuple Nuget Pakets . Visual Studio hat das verstanden und alles war in Ordnung mit der Welt.
Mads schrieb jedoch auch:
Aus diesem Grund wird die Verwendung von C # 8.0 nur auf Plattformen unterstützt, die .NET Standard 2.1 implementieren.
... was, wenn dies zutrifft, die Verwendung von C # 8 mit jeder Version von .NET Framework und sogar in .NET Standard 2.0-Bibliotheken ausgeschlossen hätte, die wir erst kürzlich als Basisziel für Bibliothekscode verwenden sollten. Sie können es nicht einmal mit .NET Core-Versionen verwenden, die älter als 3.0 sind, da auch diese nur .NET Standard 2.0 unterstützen.
Die Untersuchung war eröffnet! - -
Jon Skeet hat eine Alpha-Version von Noda-Time mit C # 8 bereit, die nur auf .NET Standard 2.0 abzielt. Er erwartet eindeutig, dass C # 8 / .NET Standard 2.0 alle Frameworks in der .NET-Familie unterstützt. (Siehe auch Jons Blog-Beitrag "Erste Schritte mit nullbaren Referenztypen" ).
Microsoft-Mitarbeiter haben die Visual Studio-Benutzeroberfläche für nullwertfähige C # 8-Referenztypen auf GitHubcsproj
erörtert , und es wird angegeben, dass sie beabsichtigen, das Legacy (Pre-.NET Core SDK-Format csproj
) zu unterstützen. Dies ist ein sehr starker Hinweis darauf, dass C # 8 mit .NET Framework verwendet werden kann. [Ich vermute, dass sie dies jetzt zurückverfolgen werden, da das Dropdown-Menü für die Sprachversion von Visual Studio 2019 deaktiviert und .NET an C # 7.3 gebunden wurde.]
Kurz nach dem berühmten Blog-Beitrag diskutierte ein GitHub-Thread die plattformübergreifende Unterstützung. Ein wichtiger Punkt, der sich herausstellte, war, dass .NET Standard 2.1 eine Markierung enthält, die angibt, dass Standardimplementierungen von Schnittstellen unterstützt werden. Für diese Funktion ist eine CLR-Änderung erforderlich, die für .NET Framework niemals verfügbar sein wird. Hier ist das Wichtige von Immo Landwerth, Programmmanager im .NET-Team von Microsoft:
Von Compilern (z. B. C #) wird erwartet, dass sie das Vorhandensein dieses Felds verwenden, um zu entscheiden, ob Standardschnittstellenimplementierungen zulässig sind oder nicht. Wenn das Feld vorhanden ist, wird erwartet, dass die Laufzeit den resultierenden Code laden und ausführen kann.
Dies alles deutete darauf hin, dass "C # 8.0 nur auf Plattformen unterstützt wird, die .NET Standard 2.1 implementieren", was eine übermäßige Vereinfachung darstellt, und dass C # 8 .NET Framework unterstützt, aber da es so viel Unsicherheit gibt, fragte ich GitHub und HaloFour antwortete:
IIRC, die einzige Funktion, die in .NET Framework definitiv nicht angezeigt wird, ist DIM (Standardschnittstellenmethoden), da dies Laufzeitänderungen erfordert. Die anderen Funktionen werden durch die Form von Klassen gesteuert, die möglicherweise nie zu .NET Framework hinzugefügt werden, aber über Ihren eigenen Code oder NuGet (Bereiche, Indizes, asynchrone Iteratoren, asynchrone Entsorgung) polygefüllt werden können.
Victor Derks kommentierte: "Die neuen nullbaren Attribute, die zum Entwerfen der komplexeren nullbaren Anwendungsfälle erforderlich sind, sind nur in System.Runtime.dll verfügbar, das mit .NET Core 3.0 und .NET Standard 2.1 geliefert wird ... [und] nicht kompatibel mit .NET Framework 4,8 "
Immo Landwerth kommentierte jedoch, dass "die überwiegende Mehrheit unserer APIs keine benutzerdefinierten Attribute benötigte, da die Typen entweder vollständig generisch oder nicht null sind" unter dem Artikel Nullable Referenztypen ausprobieren
Ben Hall hat das Problem Verfügbarkeit nullbarer Attribute außerhalb von Core 3.0 auf GitHub angesprochen , wobei die folgenden Kommentare von Microsoft-Mitarbeitern zu beachten sind:
C # 8 wird nur unter .net Core 3.0 und .net Standard 2.1 vollständig unterstützt. Wenn Sie die Projektdatei manuell bearbeiten, um C # 8 mit .net Core 2.1 zu verwenden, befinden Sie sich in einem nicht unterstützten Gebiet. Einige C # 8-Funktionen funktionieren gut, einige C # 8-Funktionen funktionieren nicht so gut (z. B. schlechte Leistung), einige C # 8-Funktionen funktionieren mit zusätzlichen Hacks und einige C # 8-Funktionen funktionieren überhaupt nicht. Sehr komplex zu erklären. Wir blockieren es nicht aktiv, damit die erfahrenen Benutzer, die darin navigieren können, dies tun können. Ich würde nicht empfehlen, dieses nicht unterstützte Mix & Match allgemein zu verwenden.
(Jan Kotas)
Menschen wie Sie, die bereit sind, sie zu verstehen - und sie zu umgehen -, können C # 8 verwenden. Der Punkt ist, dass nicht alle Sprachfunktionen auf untergeordneten Zielen funktionieren.
(Immo Landwerth)
Visual Studio 2019
In der RTM-Version von Visual Studio 2019 Version 16.3 - der Startversion für C # 8.0 - wurde eine wesentliche Änderung vorgenommen: Die Dropdown-Liste für die Sprachauswahl wurde deaktiviert:
Microsofts Begründung hierfür lautet:
In Zukunft wird ... jede Version jedes Frameworks eine einzige unterstützte und Standardversion haben, und wir werden keine beliebigen Versionen unterstützen. Um diese Änderung in der Unterstützung widerzuspiegeln, deaktiviert dieses Commit das Kombinationsfeld für die Sprachversion dauerhaft und fügt einen Link zu einem Dokument hinzu, in dem die Änderung erläutert wird.
Das Dokument, das geöffnet wird, ist die Versionierung in C # -Sprache . Hier wird NUR C # 8.0 als Standardsprache für .NET Core 3.x aufgeführt. Es wird auch bestätigt, dass jede Version jedes Frameworks künftig eine einzige unterstützte und Standardversion haben wird und dass man sich nicht mehr auf den Framework-Agnostizismus der Sprache verlassen kann.
Die Sprachversion kann für .NET Framework-Projekte weiterhin auf 8 erzwungen werden, indem die .csproj-Datei bearbeitet wird.
Vorbehalt Emptor
Die C # 8 / .NET Framework-Kombination wird von Microsoft nicht offiziell unterstützt. Es ist, sagen sie, nur für Experten.
<Nullable>enable</Nullable>
in dercsproj
. Es scheint zu funktionieren, wenn#nullable enable
Direktiven verwendet werden. Siehe auch: github.com/dotnet/project-system/issues/5551Laut diesem Blogeintrag ist die Sprache tatsächlich an das Framework gebunden:
quelle
quelle