Revisando código ajeno, me he encontrado con un ejemplo de uso del operador null coalescing assignment de C# que me ha parecido muy elegante y quería compartirlo con vosotros.
Como recordaréis, este operador, introducido en C# 8, es una fórmula muy concisa para asignar un valor a una variable si ésta previamente es null, una mezcla entre el operador de asignación y el null coalescing operator que disfrutamos desde C# 2:
Related Articles
// C# "clásico":
var x = GetSomething();
...
if(x == null) {
x = GetSomethingElse();
}
// Usando null coalescing operator (C# 2)
var x = GetSomething();
...
x = x ?? GetSomethingElse();
// Usando null coalescing assignment (C# 8)
var x = GetSomething();
...
x ??= GetSomethingElse();
Pero, además, al igual que otras asignaciones, este operador retorna el valor asignado, lo que nos permite encadenar asignaciones y realizar operaciones adicionales en la misma línea.
Por ejemplo, observad el siguiente código:
Console.WriteLine(y ??= "Hello, World!");
Aquí, básicamente lo que hacemos es asignar el valor "Hello, World!" a la variable si ésta contiene un nulo, y luego imprimirlo por consola. Y si no es nulo, simplemente se imprime su valor actual.
El código que he me ha llamado la atención sigue más o menos esa línea, y se trataba de un método que debía obtener un valor desde un origen de datos y dejarlo cacheado para llamadas posteriores al mismo. En C# "de toda la vida", más o menos podría ser algo así:
public class MyClass
{
private string _cachedValue;
...
public async Task GetValueAsync()
{
if(_cachedValue == null)
{
_cachedValue = await GetValueFromSlowStorageAsync();
}
return _cachedValue;
}
}
La implementación que me ha parecido muy concisa y elegante es la siguiente:
public class MyClass
{
private string _cachedValue;
...
public async Task GetValueAsync()
=> _cachedValue ??= await GetValueFromSlowStorageAsync();
}
En una única expresión estamos consiguiendo:
- Si el valor estaba previamente cacheado, lo retornamos sin hacer nada más.
- En caso contrario, lo obtenemos desde la fuente de datos y lo almacenamos en la variable
_cachedValue
, de forma que llamadas posteriores retornarán el valor cacheado. - Finalmente, retornamos el valor recién obtenido para que el cliente del método lo reciba.
Bonito, ¿verdad?
Publicado en Variable not found.