Compartir a través de


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 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:

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:

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.

Consulte también