Ya va quedando menos para el lanzamiento de .NET 9 y tenemos disposibles algunas de las novedades que incluirá C# 13 en su lanzamiento A continuación revisamos algunas de ellas.
Puedes encontrar el código fuente de los ejemplos en repositorio: https://github.com/fjvela/csharp-13
params collections
El modificador params
nos permite pasar un número variable de argumentos a un método. Hasta el momento estaba limitado unicamente al uso con tipos de datos Array.
var persons = new List<Person>
{
new Person("Mads", "Torgersen"),
new Person("Dustin", "Campbell"),
new Person("Kathleen", "Dollard")
};
static void WriteNames(params string[] names)
=> Console.WriteLine(String.Join(", ", names));
WriteNames(persons.Select(person => person.FirstName).ToArray());
internal class Person( string Name, string FirstName)
{
public string Name { get; set; }
public string FirstName { get; set; }
}
C# 13 extiende el modificador permitiendonos trabajar con cualquier tipo de colección, tales como: System.Span<T>_, _System.ReadOnlySpan<T>
, y tipos de datos que implementan la interfaz System.Collections.Generic.IEnumerable<T>
.
static void WriteNames(params IEnumerable<string> names)
=> Console.WriteLine(String.Join(", ", names));
WriteNames(persons.Select(person => person.FirstName));
WriteNames(from p in persons select p.FirstName);
New lock type and semantics
.NET 9 permitirá bloquear el acceso a recursos compartidos se pueda realizar de una manera más simple, eficiente y menos ambigua a través de la clase System.Threading.Lock
.
Para poder usar esta nueva clase en nuestras aplicaciones existentes, solo tendremos que sustituir private object myLock = new object();
por private System.Threading.Lock myLock = new System.Threading.Lock();
. C# automáticamente generará las llamadas necesarias a la API para usar la nueva clase.
public class ClassLockTwo
{
private System.Threading.Lock myLock = new System.Threading.Lock();
public void MyMethod()
{
lock (myLock)
{
// Your code
}
}
}
New escape sequence - \e.
C# 13 introduce la secuencia de espace \e
. Esta secuencia equivale al código unicode \u001b
.
Console.WriteLine("\e[1mThis is a bold text\e[0m");
Console.ReadLine();
Implicit indexer access in object initializers
En C# podemos utilizar el operador ^
para acceder a un elemento de un Array desde el final del mismo. Con C# 13, podemos utilizarlo para inicializar elementos de un Array desde el final del mismo.
var countdown = new TimerRemaining(10)
{
Buffer =
{
[^1] = 0,
[^10] = 9
}
};
Console.WriteLine($"First: {countdown.Buffer.First()} Last: {countdown.Buffer.Last()}");
Console.ReadLine();
class TimerRemaining(int bufferSize)
{
public int[] Buffer { get; set; } = new int[bufferSize];
}
ref struct
A continuación podemos comprobar algunas novedades relacionadas con el tipo ref struct
y C# 13.
Enable ref locals and unsafe contexts in iterators and async methods
Para versiones anteriores a C# 13, no es posible utilizar los tipos ref struct
en metodos iteradores (yield return
). En los métodos asincronos (async
) tampoco se pueden declarar variables de este tipo ni pueden ser usadas en contextos inseguros. C# 13 nos permitirá hacer uso de este tipo en todos estos casos de uso.
ref struct ClassOne
{
public int Current => 0;
public bool MoveNext() => false;
public void Dispose() { }
}
class ClassTwo
{
public ClassOne GetEnumerator() => new ClassOne();
async void M()
{
await Task.Yield();
using (new ClassOne()) { }
lock (new System.Threading.Lock()) { }
await Task.Yield();
}
}
Allow ref struct types as arguments for type parameters in generics.
Versiones anteriores a C# 13 no permiten hacer uso del tipo ref struct
como parámetro generico de un método. A partir de esta versión ya es posible:
T Identity<T>(T p)
where T : allows ref struct
=> p;
var local = Identity(new User());
Console.ReadLine();
ref struct User
{
}