C# 7.0 – Specification – Pattern Matching
Otra de las mejoras incorporadas a C# 7.0 es lo que denominamos como Pattern Matching.
Se trata de un concepto abstracto en sí, por el cual se puede probar que un valor tiene una determinada forma, y que podemos extraer información del valor cuando cumple esa forma o patrón esperado.
De momento, el uso de la coincidencias de patrones, están disponibles como:
- Constant patterns
- Type patterns
- Var patterns
Pero la idea es que se añadan más patrones a C# en un futuro.
De acuerdo a todo esto, se está trabajando en la mejora de este patrón por dos vías.
- A través de expresiones is, las cuales pueden tener un patrón en el lado derecho en lugar de solo un tipo.
- A través de claúsulas case, para buscar la coincidencia con un patrón, y no sólo en valores constantes.
También para un futuro, se está pensando en más lugares en los que los patrones podrían estar implicados.
De hecho, las variables pueden ser declaradas en medio de una expresión, y utilizadas dentro del alcance en el que se encuentra el código.
Pero vayamos con un ejemplo práctico que ayude a entender mejor como funciona esta característica del lenguaje.
En concreto, el siguiente ejemplo escrito en C# 7.0 usa is y switch:
private class Cat { public string Name { get; set; } } private class Dog { public string Name { get; set; } } private class Horse { public string Name { get; set; } } private static void PatternMatching() { Console.WriteLine("is-expressions"); ConvertToUpperCase("\tpattern matching"); Console.WriteLine("switch-statements"); Console.WriteLine("\t" + WhoIam(new Dog { Name = "Pupi" })); try { Console.WriteLine("throwing an exception"); Console.WriteLine("\t" + WhoIam(new Tuple<string>("foo"))); } catch (Exception ex) { Console.WriteLine("\t" + ex.Message); } } private static void ConvertToUpperCase(object o) { // Constant pattern (null) if (o is null) return; // Type pattern (int i) if (!(o is string s)) return; Console.WriteLine(s.ToUpper()); } private static string WhoIam(object o) { switch (o) { case Cat s: return $"{o.GetType().Name} is {s.Name}"; case Dog s: return $"{o.GetType().Name} is {s.Name}"; case Horse s: return $"{o.GetType().Name} is {s.Name}"; default: throw new ArgumentException(message: "the object is not a recognized expected object", paramName: nameof(o)); } }
¡Happy Coding!