Novedades de C# 12
C# 12 incluye las siguientes características nuevas. Puede probar estas características con la versión más reciente de visual Studio 2022 o el SDK de .NET 8.
constructores principales: se introdujo en visual Studio 2022, versión 17.6 Preview 2.
Expresiones de colección: se introdujeron en Visual Studio 2022, versión 17.7 Preview 5.
Matrices insertadas: introducidas en la versión preliminar 3 17.7 de Visual Studio versión 2022.
parámetros opcionales en expresiones lambda: se introdujo en Visual Studio 2022, versión 17.5 Preview 2.
ref readonly
parámetros - Introducidos en la versión preliminar 2 17.8 de Visual Studio versión 2022.Alias de cualquier tipo: introducido en la versión preliminar 3 17.6 de Visual Studio versión 2022.
atributo Experimental: se introdujo en visual Studio 2022, versión 17.7, versión preliminar 3.
Interceptores - Característica en vista previa Introducidas en la versión preliminar 3 17.7 de Visual Studio versión 2022.
C# 12 es compatible con .NET 8. Para obtener más información, vea Control de versiones del lenguaje C#.
Puede descargar el más reciente SDK del .NET 8 desde la página de descargas de .NET . También puede descargar visual Studio 2022, que incluye el SDK de .NET 8.
Nota
Estamos interesados en sus comentarios sobre estas características. Si encuentra problemas con cualquiera de estas nuevas características, cree un nuevo problema en el repositorio dotnet/roslyn.
Constructores principales
Ahora puede crear constructores principales en cualquier class
y struct
. Los constructores principales ya no están restringidos a los tipos record
. Los parámetros del constructor principal están en el ámbito de todo el cuerpo de la clase. Para asegurarse de que todos los parámetros del constructor principal quedan definitivamente asignados, todos los constructores declarados explícitamente deben llamar al constructor principal utilizando la sintaxis this()
. Agregar un constructor principal a un class
impide que el compilador declare un constructor sin parámetros implícito. En un struct
, el constructor sin parámetros implícito inicializa todos los campos, incluidos los parámetros del constructor principal en el patrón de 0 bits.
El compilador genera propiedades públicas para los parámetros del constructor principal solo en tipos de record
, ya sea de tipo record class
o record struct
. Es posible que las clases y estructuras no record no siempre quieran este comportamiento para los parámetros del constructor principal.
Puede obtener más información sobre los constructores principales en el tutorial acerca de , que explora los constructores principales, y en el artículo de constructores de instancia .
Expresiones de colección
Las expresiones de colección presentan una nueva sintaxis terse para crear valores de colección comunes. Insertar otras colecciones en estos valores es posible mediante un elemento de propagación ..e
.
Se pueden crear varios tipos similares a la colección sin necesidad de compatibilidad con BCL externa. Estos tipos son:
- Tipos de matriz, como
int[]
. - System.Span<T> y System.ReadOnlySpan<T>.
- Tipos que admiten inicializadores de colección, como System.Collections.Generic.List<T>.
En los ejemplos siguientes se muestran los usos de expresiones de colección:
// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];
// Create a list:
List<string> b = ["one", "two", "three"];
// Create a span
Span<char> c = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];
// Create a jagged 2D array:
int[][] twoD = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
// Create a jagged 2D array from variables:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[][] twoDFromVariables = [row0, row1, row2];
El elemento de dispersión ..e
en una expresión de colección añade todos los elementos de esa expresión. El argumento debe ser un tipo de colección. En los ejemplos siguientes se muestra cómo funciona el elemento de propagación:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];
foreach (var element in single)
{
Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,
El elemento spread evalúa cada elemento de la expresión de enumeraciones. Cada elemento se incluye en la colección de salida.
Puede usar expresiones de colección en cualquier lugar donde necesite una colección de elementos. Pueden especificar el valor inicial de una colección o pasarse como argumentos a métodos que toman tipos de colección. Puede obtener más información sobre las expresiones de colección en el artículo de referencia del lenguaje sobre expresiones de colección o la especificación de características de .
Parámetros ref readonly
C# agregó in
parámetros como una manera de pasar referencias de solo lectura. Los parámetros in
permiten tanto variables como valores y se pueden usar sin ninguna anotación en los argumentos.
La adición de parámetros de ref readonly
permite mayor claridad para las API que podrían usar parámetros de ref
o parámetros de in
:
- Las API creadas antes de la introducción de
in
podrían usarref
aunque el argumento no se modifique. Esas API se pueden actualizar conref readonly
. No será un cambio importante para los autores de llamadas, como sería si el parámetroref
se cambiara ain
. Un ejemplo es System.Runtime.InteropServices.Marshal.QueryInterface. - Las API que toman un parámetro
in
, pero requieren lógicamente una variable. Una expresión de valor no funciona. Un ejemplo es System.ReadOnlySpan<T>.ReadOnlySpan<T>(T). - Las API que usan
ref
porque requieren una variable, pero no mutan esa variable. Un ejemplo es System.Runtime.CompilerServices.Unsafe.IsNullRef.
Para obtener más información sobre los parámetros de ref readonly
, consulte el artículo sobre los modificadores de parámetros en la referencia del lenguaje o los parámetros de ref de solo lectura especificación de características.
Parámetros lambda predeterminados
Ahora puede definir valores predeterminados para parámetros en expresiones lambda. La sintaxis y las reglas son las mismas que agregar valores predeterminados para los argumentos a cualquier método o función local.
Puede obtener más información sobre los parámetros predeterminados en las expresiones lambda del artículo sobre expresiones lambda.
Alias de cualquier tipo
Puede usar la directiva de alias using
para asignar un alias a cualquier tipo, no solo a los tipos nombrados. Esto significa que puede crear alias semánticos para tipos de tupla, tipos de matriz, tipos de puntero u otros tipos no seguros. Para obtener más información, consulte la especificación de características. Para ver un tutorial de refactorización de ejemplo, consulte Refactorización del código mediante alias de cualquier tipo en el blog de .NET.
Matrices insertadas
El equipo de runtime usa matrices insertadas y otros autores de bibliotecas para mejorar el rendimiento de las aplicaciones. Las matrices insertadas permiten a un desarrollador crear una matriz de tamaño fijo en un tipo de struct
. Una estructura con un búfer insertado debe proporcionar características de rendimiento similares a un búfer de tamaño fijo no seguro. Es probable que no declare sus propias matrices insertadas, pero las usará de forma transparente cuando se exponen como System.Span<T> o System.ReadOnlySpan<T> objetos de las API en tiempo de ejecución.
Una matriz insertada se declara de forma similar a la siguiente struct
:
[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
private int _element0;
}
Los/Las usas como cualquier otra matriz:
var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
buffer[i] = i;
}
foreach (var i in buffer)
{
Console.WriteLine(i);
}
La diferencia es que el compilador puede aprovechar la información conocida sobre una matriz insertada. Es probable que consuma matrices insertadas como lo haría con cualquier otra matriz. Para obtener más información sobre cómo declarar matrices insertadas, consulte la referencia del lenguaje sobre los struct
tipos de.
Atributo experimental
Los tipos, métodos o ensamblados se pueden marcar con el System.Diagnostics.CodeAnalysis.ExperimentalAttribute para indicar una característica experimental. El compilador emite una advertencia si accede a un método o tipo anotado con el ExperimentalAttribute. Todos los tipos incluidos en un ensamblado marcado con el atributo Experimental
son experimentales. Puede leer más en el artículo sobre los atributos generales de leídos por el compiladoro la especificación de características de .
Interceptores
Advertencia
Los interceptores son una característica experimental, disponible en modo de vista previa con C# 12. La característica puede estar sujeta a cambios importantes o eliminación en una versión futura. Por lo tanto, no se recomienda para aplicaciones de producción o ya publicadas.
Para usar interceptores, el proyecto de usuario debe especificar la propiedad <InterceptorsPreviewNamespaces>
. Se trata de una lista de espacios de nombres que pueden contener interceptores.
Por ejemplo: <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>
Un interceptor es un método que puede, de forma declarativa, sustituir una llamada a un método interceptable por una llamada a sí mismo en tiempo de compilación. Esta sustitución se produce al hacer que el interceptor declare las ubicaciones de origen de las llamadas que intercepta. Los interceptores proporcionan una capacidad limitada para cambiar la semántica del código existente al agregar código nuevo a una compilación, por ejemplo, en un generador de código fuente.
Utilizas un interceptor como parte de un generador de código fuente para modificar una compilación de origen existente, en lugar de agregarle código. El generador de origen sustituye las llamadas a un método interceptable con una llamada al método interceptor.
Si está interesado en experimentar con interceptores, puede obtener más información leyendo la especificación de características de . Si usa la característica, asegúrese de mantenerse al día con los cambios en la especificación de características para esta característica experimental. Si se finaliza la característica, agregaremos más instrucciones en este sitio.