0

.Net 7 Preview 7

El 9 de agosto se enunciaron las novedades de .Net 7. En este caso la vista previa número 7. En esta versión preliminar se incluyen mejoras en System.LINQ, permisos de archivo de Unix, estructuras de bajo nivel, generación de fuente p/Invoke, generación de código y websockets. Veamos qué novedades tenemos.

Pedidos simplificados con System.LINQ

En System.Linq tenemos los métodos Order y OrderDescending, que cumplen la funcionalidad de ordenar un IEnumerable según T.

Antes lo usábamos de esta manera:

var data = new[] { 2, 1, 3 };
var sorted = data.OrderBy(static e => e);
var sortedDesc = data.OrderByDescending(static e => e);

Ahora podemos hacerlo de la siguiente:

var data = new[] { 2, 1, 3 };
var sorted = data.Order();
var sortedDesc = data.OrderByDescending();

Soporte para modos de archivo Unix

.NET no tenía soporte incorporado para obtener y configurar permisos en archivos de Unix, que controla qué usuarios pueden leer, escribir y ejecutar archivos y directorios. Podíamos hacerlo de una manera manual, pero están expuestas de manera diferente en diferentes distribuciones. Por ejemplo, en Ubuntu puede que tengamos que pinvoke a __xstat, en RedHat a stat, y así sucesivamente. Esto hace que una API .NET de primera clase sea importante.

En la versión preliminar 7, se introdujo una nueva enumeración:

public enum UnixFileMode
{
    None,
    OtherExecute, OtherWrite, OtherRead,
    GroupExecute, GroupWrite, GroupRead,
    UserExecute, UserWrite, UserRead,
     ...
}

También, tenemos API File.GetUnixFileMode y File.SetUnixFileMode que obtienen y establecen el modo de archivo en una ruta o un identificador (descriptores de archivo). Además de una nueva propiedad en FileInfo y DirectoryInfo llamada UnixFileMode.

Por otro lado, tenemos una nueva sobrecarga de Directory.CreateDirectory y una nueva propiedad en FileStreamOptions que nos permite crear un directorio o archivo con un modo particular de una sola vez. Tengamos en cuenta que cuando la usamos, todavía se aplica umask, como cuando lo hacemos de una consola o shell.

Cómo lo usamos:

// Create a new directory with specific permissions
Directory.CreateDirectory("myDirectory", UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);

// Create a new file with specific permissions
FileStreamOptions options = new()
{
    Access = FileAccess.Write,
    Mode = FileMode.Create,
    UnixCreateMode =  UnixFileMode.UserRead | UnixFileMode.UserWrite,
};
using FileStream myFile = new FileStream("myFile", options);

// Get the mode of an existing file
UnixFileMode mode = File.GetUnixFileMode("myFile");

// Set the mode of an existing file
File.SetUnixFileMode("myFile", UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute)

Mejoras en la estructura de bajo nivel: soporte de campo de referencia

Los tiempos de ejecución de .NET 7 ahora tenemos soporte completo para campos de referencia dentro de los tipos ByRefLike (estructura de referencia). Hubo un extenso diseño de lenguaje detrás de esta función tan solicitada sobre la que los usuarios pueden leer: mejoras de estructura de bajo nivel. Con esta característica, los tipos que antes requerían un manejo especializado en los tiempos de ejecución (por ejemplo, Span<T> y ReadOnlySpan<T>), ahora se puede implementar completamente en C#.

Generador de fuente LibraryImport P/Invoke

El generador de código LibraryImport ahora está disponible de manera compatible para todos los usuarios. Este generador de código fuente está diseñado para ser un reemplazo directo para la mayoría de los usos de DllImport, tanto en el producto de tiempo de ejecución como en el código de usuario. Todas las bibliotecas de .NET han adoptado LibraryImport.

Como era antes:

public static class Native
{
    [DllImport(nameof(Native), CharSet = CharSet.Unicode)]
    public extern static string ToLower(string str);
}

Como es ahora:

public static class Native
{
    [LibraryImport(nameof(Native), StringMarshalling = StringMarshalling.Utf16)]
    public static partial string ToLower(string str);
}

ClientWebSocket upgrade response details

ClientWebSocket anteriormente no proporcionó ningún detalle sobre la respuesta de actualización. Esta información sobre los encabezados de respuesta y el código de estado puede ser importante.

En caso de falla, el código de estado nos puede ayudar a distinguir entre errores recuperables y no recuperables (el servidor no admite sockets web en absoluto frente a un pequeño error transitorio). Los encabezados también pueden contener información adicional sobre cómo manejar la situación.

En caso de una conexión exitosa los encabezados también son útiles, por ejemplo, pueden contener un token vinculado a una sesión, alguna información relacionada con la versión del subprotocolo, o el servidor puede dejar de funcionar pronto, etc.

Como se usa:

ClientWebSocket ws = new();
ws.Options.CollectHttpResponseDetails = true;
try
{
    await ws.ConnectAsync(uri, default);
    // success scenario
    ProcessSuccess(ws.HttpResponseHeaders);
    ws.HttpResponseHeaders = null; // clean up (if needed)
}
catch (WebSocketException)
{
    // failure scenario
    if (ws.HttpStatusCode != null)
    {
        ProcessFailure(ws.HttpStatusCode, ws.HttpResponseHeaders);
    }
}

Mejorar en CodeGen

La comunidad ha estado muy activa, pueden consultar los links si lo desean, se mejoró lo siguiente:

Mejoras en Loop Optimizations.

Conclusiones

Esta nueva preview tiene algunas mejoras significativas pero poco funcionales. Personalmente, he tenido problemas con el tema de permisos en Unix, esto me ayudará mucho. Creo que se están guardando algunas cosas para la próxima preview. Veremos en próximos post las novedades que vienen.

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *