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 .

C# 12 es compatible con .NET 8. Para obtener más información, vea Control de versiones del lenguaje C#.

Puede descargar el SDK de .NET 8 más reciente de 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 se asignan definitivamente todos los parámetros del constructor principal, todos los constructores declarados explícitamente deben llamar al constructor principal mediante la sintaxis this(). Agregar un constructor principal a class impide que el compilador declare un constructor sin parámetros implícito. En struct, el constructor implícito sin parámetros 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 record, ya sean tipos record class o record struct. Es posible que las clases y estructuras que no son de registro 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 para explorar constructores principales y en el artículo sobre constructores de instancias.

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 operador de propagación ...

Se pueden crear varios tipos similares a la colección sin necesidad de compatibilidad con BCL externa. Estos tipos son:

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 operador de propagación, .. en una expresión de colección reemplaza su argumento por los elementos de esa colección. El argumento debe ser un tipo de colección. En los ejemplos siguientes se muestra cómo funciona el operador 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 operando de un operador de propagación es una expresión que se puede enumerar. El operador spread evalúa cada elemento de la expresión de enumeraciones.

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.

Parámetros ref readonly

C# agregó in parámetros como una manera de pasar referencias de solo lectura. parámetros de in permiten variables y valores, y se pueden usar sin ninguna anotación en 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 :

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 alias de cualquier tipo, no solo de tipos con nombre. 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.

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;
}

Se usan 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 tipos de struct.

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 tiene acceso 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 atributos generales leídos por el compilador o la especificación de características.

Interceptores

Advertencia

Los interceptores son una característica experimental, disponible en modo de vista previa con C# 12. Esta característica puede estar sujeta a cambios importantes o eliminarse 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 instalación limitada para cambiar la semántica del código existente agregando código nuevo a una compilación, por ejemplo, en un generador de origen.

Use un interceptor como parte de un generador de origen para modificarlo, en lugar de agregar código a una compilación de origen existente. 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 los interceptores, puede obtener más información en la especificación de características. Si usa la característica, asegúrese de mantenerse al día con los cambios en la especificación de características de esta característica en experimental. Una vez finalizada la característica, agregaremos más instrucciones en este sitio.

Consulte también