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.

Por favor síguenos y dale me gusta: