Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

18 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 20 de junio de 2017
C#Continuamos esta serie sobre las novedades incluidas en C#7, y en esta ocasión vamos a ver una pequeña mejora en el lenguaje que seguro nos será de utilidad para simplificar código muy frecuente: las expresiones throw.

Fijaos en un código como el siguiente, que seguro que habéis escrito cientos de veces, donde utilizamos el constructor de una clase para recibir sus dependencias y almacenarlas en miembros de la instancia:
public class MyService: IMyService
{
    private readonly IDependency _first;
    private readonly IAnotherDependency _second;

    public MyService(IDependency first, IAnotherDependency second)
    {
        if (first==null)
            throw new ArgumentNullException("first");

        if (second == null) // O mejor, usando el operador nameof
            throw new ArgumentNullException(nameof(second));

        _first = first;
        _second = second;
    }

    ...
}

Habréis reconocido el patrón: hacemos una comprobación de precondiciones, y lanzamos una excepción con throw en función del resultado de ésta.

Pues bien, en C# 7 podemos simplificar esta sintaxis debido a que throw es considerada una expresión a efectos de compilación. Es decir, con la última versión de C# podemos simplificar el método anterior de la siguiente forma, y compilará correctamente:
public MyService(IDependency first, IAnotherDependency second)
{
    _first = first ?? throw new ArgumentNullException("first");
    _second = second ?? throw new ArgumentNullException(nameof(second));
}
Otro ejemplo de uso, aunque de utilidad y legibilidad dudosa, podría ser el siguiente:
public static int Divide(int a, int b)
{
    return a / (b != 0 ? b: throw new ArgumentOutOfRangeException(nameof(b)));
}
Asimismo, dado que esta nueva capacidad permite lanzar excepciones desde el interior de expresiones, puede ser utilizada en los expression bodied members.

Con versiones anteriores del lenguaje no podíamos incluir un throw en un miembro de este tipo porque el lanzamiento de excepciones no era compatible con expresiones. Esto obligaba, por ejemplo, a escribir verbosos getters en ocasiones en las que simplemente queríamos lanzar una excepción, por ejemplo:
public interface IMyInterface
{
    string SomeValue { get; }
}

// C# 6 y anteriores 
public class Foo : IMyInterface
{
    public string SomeValue
    {
        get { throw new NotImplementedException(); }
    }
}
En C# 7, de nuevo, podríamos simplificarlo bastante:
public class Foo : IMyInterface
{
    public string SomeValue => throw new NotImplementedException();
}
En fin, no es una mejora espectacular, pero es uno de esos pequeños detalles que nos facilitan un poquito el día a día y siguen haciendo de C# un mejor lenguaje.

Otros posts de esta serie:
Publicado en Variable not found.

Aún no hay comentarios, ¡sé el primero!