C# 8.0 – Specification – Pattern Matching – Property Patterns
Índice general – C# 8.0 – Specification
Dentro de Pattern Matching, encontramos también una funcionalidad con respecto a las propiedades, la que se denomina Property Patterns.
La idea detrás de Property Patterns es la de permitir evaluar la propiedad de un determinado objeto para devolver un resultado de acuerdo a esa evaluación.
Veamos esto con un ejemplo.
Partimos de la base de tener una clase con dos propiedades, como por ejemplo:
private class Person { public int IdDiscount { get; set; } public string Name { get; set; } }
Partiendo de esta clase, vamos a suponer que vamos a analizar la propiedad IdDiscount, y si dicha propiedad es 1 devolverá un descuento del 20%, si es 2 un 10% y si es otro valor, 0% de descuento.
La implementación de este patrón quedará por lo tanto de la siguiente forma:
private static decimal PatternMatchingPropertyPatterns(Person person) => person switch { { IdDiscount: 1 } => 0.2M, { IdDiscount: 2 } => 0.1M, _ => 0M };
Así que las llamadas siguientes darán como resultado 20%, 10% y 0%:
PatternMatchingPropertyPatterns(new Person() { IdDiscount = 1, Name = "John" } PatternMatchingPropertyPatterns(new Person() { IdDiscount = 2, Name = "Rose" } PatternMatchingPropertyPatterns(new Person() { IdDiscount = 3, Name = "Mary" }
Del ejemplo anterior, debemos destacar el subrayado _ que es como utilizar default como comodín.
Cualquier valor que no se encuentre dentro del IdDiscount esperado, irá a esta parte del código como evaluación de su propiedad.
Ahora imaginemos que pasamos un null a la función PatternMatchingPropertyPatterns(null), ¿cómo se comportará?.
Por ejemplo el siguiente código:
try { Console.WriteLine($"null as {PatternMatchingPropertyPatterns(null)}%"); } catch (Exception ex) { Console.WriteLine(ex.Message); }
La llamada a la función en este caso devolverá un resultado correcto de 0%.
Lo que hace el evaluador es mirar si se cumple algunas de las premisas inicadas para IdDiscount, y en caso contrario, devolverá el valor por defecto.
El caracter _ se ocupará de ello.
Ahora bien, ¿qué pasa si lo que queremos hacer es lanzar una excepción en el caso de que venga null, pero devolver 0% en el resto de casos en los que no sea null pero IdDiscount tampoco sarisfaga el patrón de evaluación?.
Al igual que _ tenemos la posibilidad de utilizar {} y de null.
De hecho, el mismo ejemplo pero cambiando el código de evalución por el que a continuación indico, cambia el resultado cuando enviamos un null:
private static decimal PatternMatchingPropertyPatterns(Person person) => person switch { { IdDiscount: 1 } => 0.2M, { IdDiscount: 2 } => 0.1M, { } => 0M, null => throw new ArgumentNullException(nameof(Person)) };
En este caso y para null, recibiremos la siguiente respuesta:
Value cannot be null. (Parameter ‘Person’)
Por lo tanto, dentro de la evaluación de una propiedad y en este caso una clase concreta, tenemos cierta flexibilidad para cubrir la práctica totalidad de situaciones con las que podemos encontrarnos.
Happy Coding!