El pasado 9 de julio de 2024, Microsoft lanzó .NET 9 Preview 6, presentando una gran cantidad de nuevas características y mejoras en todo el framework. Esta versión incluye actualizaciones en el runtime, SDK, .NET MAUI, ASP.NET Core y C#. Algunos de los aspectos destacables de esta versión preliminar.
Actualizaciones del Runtime
El Runtime de .NET en .NET 9 Preview 6 introduce varias optimizaciones y mejoras:
- Generación de Código ARM64: Instrucciones mejoradas para cargar y almacenar datos, mejorando el tiempo de ejecución y el rendimiento.
- Disposición del Código: Mejora en el orden de los bloques básicos para maximizar el comportamiento de fallthrough y la densidad de código caliente, reduciendo el número de instrucciones de bifurcación.
- Optimización de Bucles: Reconocimiento de oportunidades para invertir las variables de contador de bucle para obtener mejoras en el rendimiento.
- Reducción de la Exposición de Direcciones: Mejor seguimiento de las direcciones de variables locales para desbloquear más oportunidades de optimización.
- Soporte para AVX10v1: Nuevo soporte para el conjunto de instrucciones SIMD, permitiendo operaciones vectorizadas en hardware habilitado para AVX10.
- Generación de Código Intrínseco de Hardware: Manejo mejorado de constantes en intrínsecos de hardware para generar código acelerado.
- Plegado de Constantes: Capacidades mejoradas de plegado de constantes para operaciones de punto flotante y SIMD.
Actualizaciones del SDK
El SDK de .NET en esta versión incluye actualizaciones importantes para mejorar la seguridad, la gestión de dependencias y la integridad de la compilación:
- NuGetAudit: Ahora emite advertencias para vulnerabilidades en dependencias transitivas, ayudando a mantener proyectos seguros.
- dotnet nuget why: Un nuevo comando para averiguar por qué un paquete transitivo está siendo utilizado por tu proyecto.
- MSBuild BuildChecks: Introducido para aplicar reglas e invariantes durante las compilaciones, similar a los Analizadores Roslyn, con nuevas reglas para la Ruta de Salida Compartida y la Detección de Escritura Doble.
Actualizaciones de .NET MAUI
El equipo de .NET MAUI se ha centrado en mejorar los fundamentos básicos del SDK para aumentar la calidad general del producto:
- Mejoras en la Calidad: Ampliación de la cobertura de pruebas, pruebas de escenarios de principio a fin y corrección exhaustiva de errores.
- .NET para Android e iOS: Actualizaciones centradas en la calidad para garantizar un desarrollo de aplicaciones robusto y confiable en ambas plataformas.
Actualizaciones de ASP.NET Core
ASP.NET Core en .NET 9 Preview 6 introduce varias mejoras para optimizar el rendimiento, la seguridad y la usabilidad:
- Fingerprinting de Activos Web Estáticos: Genera automáticamente versiones con huellas digitales de los activos estáticos para mejorar el almacenamiento en caché y reducir los tiempos de carga.
- Trazabilidad Distribuida Mejorada para SignalR: Capacidades de trazabilidad mejoradas para las llamadas a métodos de hubs de SignalR.
- Mejoras en Microsoft.AspNetCore.OpenAPI: Proveedor de finalización mejorado y soporte para los atributos
[Required]y[DefaultValue], junto con transformadores de esquemas. - Analizador para
[Authorize]y[AllowAnonymous]: Nuevo analizador para advertir cuando[Authorize]es anulado por[AllowAnonymous]. - ComponentPlatform Renombrado a RendererInfo: Refleja las convenciones de nomenclatura actualizadas.
- División de Encabezados HTTP/2 Grandes en Varios Marcos: Asegura un mejor manejo de encabezados grandes.
Actualizaciones de C#
C# 13, ahora es parte de .NET 9 Preview 6, introduce varias características nuevas que amplían las capacidades del lenguaje y mejoran la experiencia de desarrollo:
- Partial Properties: Diseñadas para soportar generadores de código fuente, haciendo que las API sean más intuitivas y naturales.
- Soporte para Constructores Primarios en el Generador de Código Fuente de Logging: El Generador de Código Fuente de Logging ahora soporta el registro utilizando clases con un constructor primario.
Ejemplo:
public partial class ClassWithPrimaryConstructor(ILogger logger)
{
[LoggerMessage(0, LogLevel.Debug, "Test.")]
public partial void Test();
}
Actualizaciones de System.Text.Json
Se han añadido y mejorado las siguientes capacidades para System.Text.Json, ejemplo:
using System.Text.Json.Schema; Console.WriteLine(JsonSchemaExporter.GetJsonSchemaAsNode(JsonSerializerOptions.Default, typeof(Book)));
public class Book
{
public string Title { get; set; }
public string? Author { get; set; }
public int PublishYear { get; set; }
}
Respecto a las Anotaciones de Nullabilidad: System.Text.Json ahora reconoce las anotaciones de nullabilidad y puede aplicarlas durante la serialización y deserialización utilizando el indicador RespectNullableAnnotations. Ejemplo:
JsonSerializerOptions options = new() { RespectNullableAnnotations = true };
JsonSerializer.Serialize(new MyClass { Value = null! }, options); // Throws exception
JsonSerializer.Deserialize<MyClass>("""{ "Value" : null }""", options); // Throws exception
record MyClass(string Value);
Requerir Parámetros de Constructor No Opcionales: System.Text.Json ahora trata los parámetros de constructor no opcionales como obligatorios durante la deserialización utilizando el indicador RespectRequiredConstructorParameters. Ejemplo:
JsonSerializerOptions options = new() { RespectRequiredConstructorParameters = true };
JsonSerializer.Deserialize<MyClass>("""{}""", options); // Throws exception
record MyClass(string Value);
Ordenación de Propiedades de JsonObject: El tipo JsonObject ahora expone APIs similares a diccionarios ordenados que permiten la manipulación explícita del orden de las propiedades. Ejemplo:
JsonObject jObj = new()
{
["key1"] = true,
["key3"] = 3
};
Console.WriteLine(jObj is IList<KeyValuePair<string, JsonNode?>>); // True
int key3Pos = jObj.IndexOf("key3") is int i and >= 0 ? i : 0;
jObj.InsertAt(key3Pos, "key2", "two");
API Adicionales de Contratos de Metadatos: La API de contrato JSON ahora expone metadatos adicionales, incluyendo información de metadatos de constructor y soporte mejorado para proveedores de atributos. Ejemplo:
namespace System.Text.Json.Serialization.Metadata;
public partial class JsonTypeInfo
{
// Typically the ConstructorInfo of the active deserialization constructor.
public ICustomAttributeProvider? ConstructorAttributeProvider { get; }
}
public partial class JsonPropertyInfo
{
public Type DeclaringType { get; }
// Typically the FieldInfo or PropertyInfo of the property.
public ICustomAttributeProvider? AttributeProvider { get; set; }
// The constructor parameter that has been associated with the current property.
public JsonParameterInfo? AssociatedParameter { get; }
}
public sealed class JsonParameterInfo
{
public Type DeclaringType { get; }
public int Position { get; }
public Type ParameterType { get; }
public bool HasDefaultValue { get; }
public object? DefaultValue { get; }
public bool IsNullable { get; }
// Typically the ParameterInfo of the parameter.
public ICustomAttributeProvider? AttributeProvider { get; }
}
Actualizaciones de Bibliotecas
Se han realizado varias actualizaciones en las bibliotecas de .NET para mejorar la funcionalidad y el rendimiento:
[GeneratedRegex] en Propiedades: C# 13 ahora admite propiedades parciales, permitiendo el uso de [GeneratedRegex] en propiedades. Ejemplo:
[GeneratedRegex("\b\w{5}\b")]
private static partial Regex FiveCharWord { get; }
Regex.EnumerateSplits: La clase Regex ahora ofrece un método EnumerateSplits que permite la entrada basada en spans sin necesidad de asignaciones. Ejemplo:
ReadOnlySpan<char> input = "¡Hola, mundo! ¿Cómo estás?";
foreach (Range r in Regex.EnumerateSplits(input, "[aeiou]"))
{
Console.WriteLine($"Split: \"{input[r]}\"");
}
OrderedDictionary<TKey, TValue>: .NET 9 introduce colecciones de diccionarios de datos genéricos OrderedDictionary<TKey, TValue>. Ejemplo:
OrderedDictionary<string, int> d = new() { ["a"] = 1, ["b"] = 2, ["c"] = 3, };
d.Add("d", 4);
d.RemoveAt(0);
d.RemoveAt(2);
d.InsertAt(0, "e", 5);
foreach (KeyValuePair<string, int> entry in d)
{
Console.WriteLine(entry);
}
ReadOnlySet: .NET 9 introduce ReadOnlySet para crear vistas de solo lectura de conjuntos.
private readonly HashSet<int> _set = new(); private readonly ReadOnlySet<int>? _setWrapper; public ReadOnlySet<int> Set => _setWrapper ??= new(_set);
allow ref struct en Bibliotecas: La restricción allows ref struct en C# 13 se usa en muchos lugares, permitiendo el paso de spans y otros ref structs como entrada.
public static string Create<TState>(int length, TState state, SpanAction<char, TState> action) where TState : allows ref struct;
Búsquedas en Colecciones con Spans: Nuevas características permiten búsquedas basadas en spans en colecciones como Dictionary y HashSet.
private readonly Dictionary<string, int> _wordCounts = new(StringComparer.OrdinalIgnoreCase);
[GeneratedRegex(@"\b\w+\b")]
private static partial Regex WordMatcher { get; }
private static Dictionary<string, int> CountWords(ReadOnlySpan<char> input)
{
Dictionary<string, int> wordCounts = new(StringComparer.OrdinalIgnoreCase);
var spanLookup = wordCounts.GetAlternateLookup<ReadOnlySpan<char>>();
foreach (Range wordRange in WordMatcher.EnumerateSplits(input))
{
ReadOnlySpan<char> word = input[wordRange];
spanLookup[word] = spanLookup.TryGetValue(word, out int count) ? count + 1 : 1;
}
return wordCounts;
}
Más APIs Basadas en Span: Se siguen añadiendo nuevas APIs basadas en span, como para operaciones con archivos y manipulaciones de cadenas.
ReadOnlySpan<char> text = ...;
File.WriteAllText(filePath, text);
ReadOnlySpan<char> text = "some arbitrary text";
return text.StartsWith('"') && text.EndsWith('"'); // false
Base64Url: La nueva clase Base64Url proporciona métodos para codificación y decodificación con Base64Url.
ReadOnlySpan<byte> bytes = ...; string encoded = Base64Url.EncodeToString(bytes);
SocketsHttpHandler por Defecto en HttpClientFactory: HttpClientFactory ahora utiliza SocketsHttpHandler por defecto, mejorando la configurabilidad y la gestión de conexiones.
Reanudación de TLS con Certificados de Cliente en Linux: Esta característica añade soporte para la reanudación de TLS de conexiones mutuamente autenticadas en Linux, mejorando la eficiencia en escenarios de servidor a servidor.
Introducción del Instrumento Metrics Gauge: System.Diagnostics.Metrics ahora proporciona el instrumento Gauge, que registra valores no aditivos, como la medición del nivel de ruido de fondo.
Meter meter = new Meter("MeasurementLibrary.Sound");
Gauge<int> gauge = meter.CreateGauge<int>(name: "NoiseLevel", unit: "dB", description: "Background Noise Level");
gauge.Record(10, new TagList { "Room1", "dB" });
Los desarrolladores pueden esperar una experiencia de desarrollo más sólida, eficiente e intuitiva en todos los aspectos del ecosistema .NET con estas actualizaciones en .NET 9 Preview 6. Esta versión contiene muchas características para distintos tipos de proyectos, ya sea que se esté pensando en crear aplicaciones web con ASP.NET Core, aplicaciones multiplataforma con.NET MAUI o aprovechando las características más recientes de C# 13.
Ingeniero de Software, docente universitario, con más de 13 años de experiencia en el área de ingeniería y arquitectura de software utilizando plataformas y tecnologías como C#, .NET Framework, .NET Core, Java, WCF, Spring Framework, Angular, Android, Ionic Framework, Amazon AWS/S3, Azure, Google Cloud Platform Digital Ocean, Linux, PostgreSQL, Oracle, SQL Server, entre otras.
Apasionado por las nuevas tecnologías, autodidacta y músico ocasional.