C# 8.0 (y superior) solo es compatible con .NET Core 3.x y versiones más recientes. Muchas de las funciones más nuevas requieren funciones de biblioteca y tiempo de ejecución introducidas en .NET Core 3.x: control de versiones del lenguaje C#
Sí, C# 8 se puede usar con .NET Framework y otros destinos anteriores a .NET Core 3.0/.NET Standard 2.1 en Visual Studio 2019 (o versiones anteriores de Visual Studio si instala un paquete NuGet ).
Lo único que se requiere es establecer la versión de idioma en 8.0 en el archivo csproj. También puede hacer esto en Directory.Build.props para aplicarlo a todos los proyectos de su solución. Lea a continuación cómo hacer esto en Visual Studio 2019, versión 16.3 y posteriores.
La mayoría de las características, pero no todas, están disponibles independientemente del marco al que se destine.
Las siguientes características son solo cambios de sintaxis; funcionan independientemente del marco:
Estos requieren nuevos tipos que no están en .NET Framework. Solo se pueden usar junto con paquetes NuGet "polyfill" o archivos de código:
Los miembros de la interfaz predeterminada no se compilarán en .NET Framework y nunca funcionarán porque requieren cambios en el tiempo de ejecución en CLR. .NET CLR ahora está congelado ya que .NET Core ahora es el camino a seguir.
Para obtener más información sobre lo que funciona y lo que no, y sobre los posibles polyfills, consulte el artículo de Stuart Lang, C# 8.0 and .NET Standard 2.0 - Doing Unsupported Things .
El siguiente proyecto de C# destinado a .NET Framework 4.8 y que usa tipos de referencia que aceptan valores NULL de C# 8 se compila en Visual Studio 16.2.0. Lo creé eligiendo la plantilla de biblioteca de clases estándar de .NET y luego editándola para apuntar a .NET Framework en su lugar:
.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; } } } Luego probé un proyecto WinForms de .NET Framework 4.5.2, usando un formato heredado .csproj , y agregué la misma propiedad de tipo de referencia anulable. Cambié el tipo de idioma en el cuadro de diálogo de configuración de compilación avanzada de Visual Studio (deshabilitado en 16.3) al latest y guardé el proyecto. Por supuesto, como este punto no se construye. Abrí el archivo del proyecto en un editor de texto y cambié lo latest para obtener una preview en la configuración de compilación PropertyGroup :
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <LangVersion>preview</LangVersion> Luego habilité el soporte para tipos de referencia anulables agregando <Nullable>enable</Nullable> al PropertyGroup principal:
<PropertyGroup> <Nullable>enable</Nullable>Recargué el proyecto y se construye.
Ha habido un cambio importante en la versión RTM de Visual Studio 2019 versión 16.3, la versión de lanzamiento para C# 8.0: el menú desplegable de selección de idioma se ha deshabilitado:
La razón de Microsoft para esto es:
En el futuro, ... cada versión de cada marco tendrá una única versión compatible y predeterminada, y no admitiremos versiones arbitrarias. Para reflejar este cambio en el soporte, esta confirmación deshabilita permanentemente el cuadro combinado de versión de idioma y agrega un enlace a un documento que explica el cambio.
El documento que se abre es Versiones del lenguaje C# . Esto enumera C# 8.0 como el idioma predeterminado para .NET Core 3.x SOLAMENTE. También confirma que cada versión de cada marco, en el futuro, tendrá una única versión compatible y predeterminada y que ya no se puede confiar en el agnosticismo del marco del lenguaje.
La versión de idioma todavía se puede forzar a 8 para proyectos de .NET Framework editando el archivo .csproj.
Cuando se escribió esta respuesta por primera vez, C# 8 estaba en versión preliminar y había mucho trabajo de detective involucrado. Dejo esa información aquí para la posteridad. Siéntase libre de omitirlo si no necesita conocer todos los detalles sangrientos.
Históricamente, el lenguaje C# ha sido en su mayoría neutral con respecto al marco , es decir, capaz de compilar versiones anteriores del marco, aunque algunas características han requerido nuevos tipos o compatibilidad con CLR.
La mayoría de los entusiastas de C# habrán leído la entrada de blog Building C# 8.0 de Mads Torgersen, que explica que ciertas características de C# 8 tienen dependencias de plataforma:
Las secuencias asíncronas, los indexadores y los rangos se basan en nuevos tipos de marcos que formarán parte de .NET Standard 2.1... .NET Core 3.0, así como Xamarin, Unity y Mono implementarán .NET Standard 2.1, pero .NET Framework 4.8 no. Esto significa que los tipos necesarios para usar estas funciones no estarán disponibles en .NET Framework 4.8.
Esto se parece un poco a Value Tuples que se introdujeron en C# 7. Esa característica requería nuevos tipos, las estructuras ValueTuple , que no estaban disponibles en las versiones de NET Framework anteriores a 4.7 o .NET Standard anteriores a 2.0. Sin embargo , C# 7 aún podría usarse en versiones anteriores de .NET, ya sea sin tuplas de valor o con ellas instalando el paquete System.ValueTuple Nuget . Visual Studio entendió esto, y todo estaba bien con el mundo.
Sin embargo, Mads también escribió:
Por este motivo, el uso de C# 8.0 solo se admite en plataformas que implementan .NET Standard 2.1.
...que, de ser cierto, habría descartado el uso de C# 8 con cualquier versión de .NET Framework y, de hecho, incluso en las bibliotecas .NET Standard 2.0, que solo recientemente se nos animó a usar como objetivo de referencia para el código de la biblioteca. Ni siquiera podría usarlo con versiones de .NET Core anteriores a la 3.0, ya que solo son compatibles con .NET Standard 2.0.
¡La investigación estaba en marcha! -
Jon Skeet tiene una versión alfa de Noda-Time que usa C# 8 lista para usar y que apunta solo a .NET Standard 2.0. Está claro que espera que C# 8/.NET Standard 2.0 sea compatible con todos los marcos de trabajo de la familia .NET. (Consulte también la publicación de blog de Jon "Primeros pasos con tipos de referencia anulables" ).
Los empleados de Microsoft han estado analizando la interfaz de usuario de Visual Studio para los tipos de referencia anulables de C# 8 en GitHub , y se afirma que tienen la intención de admitir el csproj heredado (formato csproj anterior al SDK de .NET Core). Esta es una indicación muy fuerte de que C# 8 se podrá usar con .NET Framework. [Sospecho que darán marcha atrás en esto ahora que el menú desplegable de la versión de idioma de Visual Studio 2019 se ha deshabilitado y .NET se ha vinculado a C# 7.3]
Poco después de la famosa publicación de blog, un hilo de GitHub discutió el soporte multiplataforma. Un punto importante que surgió fue que .NET Standard 2.1 incluirá un marcador que indica que se admiten las implementaciones predeterminadas de las interfaces : la función requiere un cambio de CLR que nunca estará disponible para .NET Framework. Esta es la parte importante, de Immo Landwerth, administrador de programas del equipo de .NET en Microsoft:
Se espera que los compiladores (como C#) utilicen la presencia de este campo para decidir si permiten o no implementaciones de interfaz predeterminadas. Si el campo está presente, se espera que el tiempo de ejecución pueda cargar y ejecutar el código resultante.
IIRC, la única característica que definitivamente no aparecerá en .NET Framework es DIM (métodos de interfaz predeterminados), ya que requiere cambios en el tiempo de ejecución. Las otras funciones están impulsadas por la forma de las clases que quizás nunca se agreguen a .NET Framework, pero que se pueden polillenar a través de su propio código o NuGet (rangos, índices, iteradores asíncronos, eliminación asíncrona).
Victor Derks comentó que "los nuevos atributos anulables necesarios para diseñar los casos de uso anulables más complejos solo están disponibles en System.Runtime.dll que se envía con .NET Core 3.0 y .NET Standard 2.1... [y] incompatible con .NET Framework 4.8"
Sin embargo, Immo Landwerth comentó que "la gran mayoría de nuestras API no necesitaban ningún atributo personalizado, ya que los tipos son completamente genéricos o no son nulos" en el artículo Pruebe los tipos de referencia anulables.
Ben Hall planteó el problema Disponibilidad de atributos anulables fuera de Core 3.0 en GitHub, y cabe destacar los siguientes comentarios de los empleados de Microsoft:
C# 8 será totalmente compatible con .net core 3.0 y .net standard 2.1 únicamente. Si edita manualmente el archivo del proyecto para usar C# 8 con .net core 2.1, se encuentra en territorio no admitido. Algunas funciones de C# 8 funcionarán bien, algunas funciones de C# 8 no funcionarán demasiado bien (p. ej., bajo rendimiento), algunas funciones de C# 8 funcionarán con trucos adicionales y algunas funciones de C# 8 no funcionarán en absoluto. Muy complejo de explicar. No lo bloqueamos activamente para que los usuarios expertos que pueden navegar a través de él puedan hacerlo. No recomendaría que esta mezcla y combinación no admitida se use ampliamente.
(Jan Kotas)
Las personas como usted que están dispuestas a comprender, y trabajar en torno a ellas, pueden usar C# 8. El punto es que no todas las características del lenguaje funcionarán en objetivos de nivel inferior.
(Immo Landwerth)
Microsoft no admite oficialmente la combinación C# 8/.NET Framework. Es, dicen, solo para expertos.
De acuerdo con esta entrada de blog, el lenguaje está realmente vinculado al marco:
Esto significa que los tipos necesarios para usar estas funciones no estarán disponibles en .NET Framework 4.8. Del mismo modo, las implementaciones de miembros de interfaz predeterminados se basan en nuevas mejoras de tiempo de ejecución, y tampoco las haremos en .NET Runtime 4.8.
Por este motivo, el uso de C# 8.0 solo se admite en plataformas que implementan .NET Standard 2.1. La necesidad de mantener estable el tiempo de ejecución nos ha impedido implementar nuevas funciones de lenguaje durante más de una década. Con la naturaleza de lado a lado y de código abierto de los tiempos de ejecución modernos, sentimos que podemos evolucionarlos de nuevo de manera responsable y diseñar el lenguaje con eso en mente. Scott explicó en su Actualización sobre .NET Core 3.0 y .NET Framework 4.8 que .NET Framework verá menos innovación en el futuro, en lugar de centrarse en la estabilidad y la confiabilidad. Dado eso, creemos que es mejor que se pierda algunas características del lenguaje que que nadie las obtenga.