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 ;)

17 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, 28 de octubre de 2014
imageSeguimos con la serie donde vamos desgranando las novedades de C# 6, y en esta ocasión vamos a ver algunas mejoras en el uso de bloques try/catch, a las que seguro podremos sacar buen partido.

En este post trataremos dos temas distintos. En primer lugar, comentaremos la introducción del soporte de await en bloques catch/finally, y seguiremos con la nueva capacidad de filtrado de excepciones.

Vamos a ello :-)

Soporte de await en bloques catch/finally

Esta nueva característica cubre una pequeña ausencia presente en las versiones anteriores del lenguaje de la que, sinceramente, no me había dado cuenta hasta la fecha. Resulta que en las versiones de C# anteriores a la 6, no estaba permitido utilizar await para esperar la finalización de una llamada asíncrona en bloques catch y finally. Por tanto, un código como el siguiente lanzaba un error de compilación:

image

Como curiosidad, el motivo de que el uso de await no estuviera soportado en este tipo de bloques en las versiones anteriores del lenguaje era simplemente "porque era muy difícil de implementar" (palabras textuales).

No sé a vosotros, pero a mí incluso me ha sorprendido que no se pudiera hacer antes. Seguro que si no lo he echado en falta es porque no me he encontrado hasta ahora con la necesidad de hacerlo, lo que puede indicar que tampoco es algo habitual (al menos por mi parte, claro) pero bueno, está bien saber que ya podremos usarlo con normalidad.

Filtros de excepciones

Hasta ahora, la granularidad de los bloques catch  de C# es a nivel de tipo de excepción. Es decir, tras un try normalmente encontramos tantos catch como tipos de excepción distintos queremos controlar, indicando así dónde queremos que se gestione la excepción cuando se produzca. Podemos ver un ejemplo del código habitual en el lateral.

Aunque este enfoque es válido en muchas ocasiones, hay otras donde sería interesante poder tener un mayor control a la hora de decidir si queremos que un bloque catch concreto gestione una excepción.

Para ello, C# 6 incorpora los nuevos exception filters, que son condiciones adicionales que podemos añadir a cada cláusula catch de forma que, si no se cumplen, el bloque será ignorado y se seguirá buscando en el resto de catchs si hay alguno que puedan manejar la excepción.

Nota: efectivamente, esto existe en VB.NET desde el principio de los tiempos. Aunque a veces pueda parecer lo contrario, no siempre C# va por delante ;)

La sintaxis de estos bloques es la siguiente:


Como podéis observar, la cosa consiste simplemente en añadir condiciones a las cláusulas catch, de forma que la excepción sólo será tratada en ese bloque si la condición evalúa a cierto. En caso contrario, se continuarán evaluando el resto de catchs hasta encontrar uno capaz de gestionar la excepción. Por ejemplo, en el caso anterior, un una excepción ServerException cuya propiedad HttpCode valga 503 será evaluada por el catch final.

Fijaos que con las versiones de C# anteriores a la 6 no sería tan sencillo solucionar este escenario. Nos veríamos obligados a introducir un único catch para la excepción ServerException y decidir en su interior si debemos tratarla, pero en caso contrario no podremos dejarla fluir para que otros catch posteriores la traten. A lo sumo podríamos relanzarla, pero el resultado tampoco sería el mismo.

Por supuesto, las condiciones pueden contener cualquier tipo de expresión booleana, como en el siguiente ejemplo:



Y aprovechando esta capacidad, es posible hacer uso y abuso de estos filtros para realizar tratamiento lateral de excepciones, es decir, realizar determinadas tareas cuando una excepción se detecta, pero permitiendo que el resto de catchs sean evaluados. Por ejemplo, en el siguiente código se guardan las excepciones ServerException en el log, pero el tratamiento final de la excepción se realizará en el último catch porque el filtro siempre retorna false:



En definitiva, de nuevo estamos ante unas novedades no muy espectaculares, pero sí útiles para cubrir escenarios que con las versiones anteriores de C# no podíamos solucionar de forma tan directa.

Otros posts de la serie sobre C# 6:
Publicado en Variable not found.

1 comentario:

Jonathan dijo...

Buen dato, la verdad no lo sabia.