Saltar al contenido

Usar la coincidencia de patrones en las declaraciones de los interruptores

Para comprender las maravillas de la comparación de patrones, comencemos considerando las siguientes clases para padres de empleados e hijos de ingenieros y desarrolladores. Nótese que, para simplificar, asumiremos que la variable llamada nombre representa el nombre completo del empleado. En este ejemplo, el lenguaje es el lenguaje de programación preferido por un desarrollador, y líder indica si el ingeniero lidera actualmente un equipo o no.

1234567891011121314151617181920212223242526272829303132333435363738394041424344classEmpleado{nombre de la cadena privada;}privado en edad;}público en edad {get{returnthis.name;}set{este.nombre =valor;}}público en edad {get{returnthis.age;}set{este. edad =valor;}}}claseIngeniero:Empleado{líder de cadena privada;líder de cadena pública {get{returnthis.leader;}}set{this.leader =valor;}}}claseDesarrollador:Empleado{líder de cadena privada;líder de cadena pública Lenguaje {get{returnthis.language;}set{this.language =valor;}}}

csharp

Usar la coincidencia de patrones en las declaraciones de los interruptores
Usar la coincidencia de patrones en las declaraciones de los interruptores

A continuación, crearemos un empleado, un desarrollador y dos objetos de ingeniería:

1234567891011121314151617181920212223242526Empleado emp =newEmployee{ Nombre ="Mike Ehrmantraut", Edad =45};Desarrollador dev =newDeveloper{ Nombre ="Walter White", Edad =27, Lenguaje ="JavaScript"}; Ingeniero eng1 =newEngineer{ Nombre ="Gus Fring", Edad =32, Líder =verdad};Ingeniero eng2 =newEngineer{ Nombre ="Hector Salamanca", Edad =49, Líder =falso};

csharp

Teniendo esto en cuenta, los siguientes escenarios nos ayudarán a ilustrar los aspectos más importantes de la coincidencia de patrones.

Ejemplo 1: El patrón de tipo

Para empezar, creemos un método llamado PrintPersonalInfo, que tomará un objeto de persona genérica como parámetro:

123456789101112publicstaticvoidPrintPersonalInfo(persona objeto) {switch(persona) {caseDeveloper d: Console.WriteLine($"{d.Nombre} es un desarrollador de {d.Edad} años de edad con {d.Habilidades de lenguaje});break;caseIngeniero e: Console.WriteLine($"{e.Nombre} es un ingeniero de {e.Edad} años de edad");break;}}

csharp

En el código de arriba, vemos:

  • La expresión de coincidencia se compara con dos objetos personalizados (Desarrollador e Ingeniero). Más exactamente, estamos comprobando el tipo de la variable de control, lo que es lo mismo que decir que estamos usando un patrón de tipo.
  • A las instancias variables d y e se les asigna el valor de persona sólo cuando la pauta se ajusta (lo que significa que están en el ámbito de aplicación sólo dentro de sus correspondientes bloques de casos y no pueden utilizarse fuera).

Si ahora llamamos a PrintPersonalInfo en cada objeto, el resultado será similar a la Fig. 1:

1234PrintPersonalInfo(emp);PrintPersonalInfo(dev);PrintPersonalInfo(eng1);PrintPersonalInfo(eng2);

csharp

Probablemente notaste que no hay un bloqueo de caso para el objeto Empleado. Esto hace que no se imprima nada cuando el método se ejecuta como PrintPersonalInfo(emp), lo que nos lleva a lo que discutiremos en el Ejemplo 2.

Ejemplo 2: Valores no mutuamente excluyentes

Para proceder, añadiremos el siguiente caso en la parte superior del bloque de interruptores:

123caseEmpleado em: Console.WriteLine($"{em.Name} es uno de nuestros empleados");break;

csharp

Cuando intentemos compilar el proyecto, obtendremos un error CS8120 ( El caso switch ya ha sido manejado por un caso anterior ), como se muestra en la Fig. 2:

El desafío aquí es que la coincidencia de patrones en la estructura del interruptor abre la puerta para valores no mutuamente exclusivos en etiquetas de cajas separadas. En general, C# 7.0 y las versiones más recientes se quejarán si detecta un caso que represente un subconjunto de una declaración anterior. En este ejemplo, tanto el Desarrollador como el Ingeniero son subclases de Empleado, lo que explica por qué obtenemos el error dos veces en la ventana de depuración en la parte inferior de la Fig. 2.

Dicho esto, podemos mover el bloque de casos correspondiente en la parte inferior de la sección del interruptor si necesitamos tener en cuenta el objeto Empleado.

Ejemplo 3: Encender las propiedades

Para este ejemplo, reemplacemos el bloque de interruptores en PrintPersonalInfo con el siguiente código:

123456789switch(persona){casoEngineer e cuando e.Leader: Console.WriteLine($"{e.Name} está actualmente liderando un equipo");break;caseEngineer e when !e.Leader: Console.WriteLine($"{e.Name} no está liderando un equipo en estos días");break;}

csharp

La Fig. 3 muestra el resultado de llamar al método sobre los mismos objetos que antes. Como era de esperar, sólo imprime un mensaje en la pantalla cuando se ejecuta como PrintPersonalInfo(eng1) e PrintPersonalInfo(eng2):

A primera vista, este ejemplo no añade mucho al número 1, excepto por el uso de la palabra clave “when” que ahora nos permite activar las propiedades del objeto. Del mismo modo, también podemos comprobar si un atributo coincide con un patrón con las siguientes etiquetas de casos válidos:

1caseEngineer e cuando e.Name.Contains("Gus"):

csharp

o

1caseDeveloper d cuando d.Language.ToUpper().Contiene("JAVASCRIPT"):

csharp

Por supuesto, esto también significa que potencialmente puede usar expresiones regulares más complejas como condiciones. La comprobación de una cadena para una subcadena dada se presenta aquí como una ilustración representativa.