Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Tip
Este artículo forma parte de la sección Aspectos básicos de los desarrolladores que ya conocen al menos un lenguaje de programación y están aprendiendo C#. Si no está familiarizado con la programación, comience primero con los tutoriales de introducción . Los desarrolladores de C# experimentados pueden usar la referencia de patrones para la sintaxis y las reglas completas.
¿Viene de otro idioma? Los patrones de C# cumplen una función similar a la comparación de patrones de Java y a los casos de match de Python. C# usa patrones en is expresiones, switch instrucciones y switch expresiones.
La coincidencia de patrones aplica un patrón a una expresión. Un patrón es una condición para probar la expresión de entrada. La entrada de patrón es esa expresión. C# evalúa la expresión de entrada; el resultado es el valor evaluado. El patrón comprueba si ese valor tiene un tipo determinado, es igual a un valor determinado o tiene una forma determinada. Cuando un patrón coincide, el código puede usar la información aprendida por la prueba, como un tipo más específico o un valor extraído de un objeto.
Puede usar un patrón en tres contextos:
- A la derecha del operador
is. - En una etiqueta
casede una instrucciónswitch. - En una rama de una expresión
switch.
Los patrones suelen ser más claros que una secuencia de instrucciones de comparación porque cada rama describe los datos que controla. Por ejemplo, el método siguiente usa una switch expresión para elegir un mensaje de entrega:
static string GetDeliveryMessage(Delivery? delivery) =>
delivery switch
{
null => "No delivery was scheduled.",
ExpressDelivery express => $"Express package {express.TrackingCode}",
StandardDelivery { Days: <= 2 } => "Standard delivery arriving soon",
_ => "Standard delivery"
};
Los patrones recursivos tienen sus propias expresiones de entrada. En StandardDelivery { Days: <= 2 }, el patrón externo recibe la expresión delivery. El patrón recursivo <= 2 recibe la Days expresión de propiedad del objeto coincidente StandardDelivery .
La expresión anterior switch es la expresión de entrada. Cada línea dentro de las llaves es un brazo de interruptor. El patrón aparece antes de =>, y el resultado aparece después. C# evalúa la expresión de entrada y, a continuación, selecciona el primer brazo, en orden de texto, cuyos patrones coinciden y cuya protección opcional when es true. La protección opcional when es una condición booleana adicional escrita después del patrón. En el ejemplo anterior se muestran los siguientes patrones:
-
nulles un patrón constante. Comprueba si ladeliveryexpresión se evalúa comonull. -
ExpressDelivery expresses un patrón de declaración con dos partes.ExpressDeliveryes la parte de prueba de tipos. Comprueba si el valor evaluado es un objeto distinto de NULL cuyo tipo de tiempo de ejecución es compatible conExpressDelivery.expresses la designación de variable: declara una variable denominadaexpressy le asigna el objeto coincidenteExpressDelivery. -
StandardDelivery { Days: <= 2 }comienza con una prueba de tipo.StandardDeliverycomprueba si el valor evaluado es un objeto distinto de NULL de ese tipo. Las llaves contienen un patrón de propiedades.Daysasigna a la propiedad que se va a inspeccionar, por lo que laDaysexpresión de propiedad se convierte en la entrada del patrón recursivo. La<= 2parte es un patrón relacional, que comprueba si el valor evaluado es menor o igual que2. -
_(subrayado) es el patrón de descarte. Coincide con cada valor evaluado, incluidonull. Dado que las ramas anteriores ya gestionannull, las entregas urgentes y las entregas estándar que llegan en un plazo de dos días, esta rama final gestiona cualquier valor restante.
Un brazo sin protección when no está protegido. Todos los brazos del primer ejemplo no están vigilados. Si una rama anterior sin guarda coincide con todos los valores evaluados con los que podría coincidir una rama posterior, la rama posterior queda subsumida. Un patrón de subsumado es uno en el que cada valor de entrada posible que coincida ya estaba coincidente con un brazo de conmutador anterior. Nunca puede coincidir, por lo que el compilador notifica un error. El brazo de descarte (_) debe ser el último porque coincide con cada expresión de entrada. Un brazo protegido no subsume un brazo posterior basado en su patrón solo porque la guardia podría ser false.
Una expresión switch es exhaustiva cuando sus brazos controlan cada expresión de entrada posible. El primer ejemplo es exhaustivo porque su último brazo de descarte abarca cualquier caso con el que no coincidan los brazos anteriores. El compilador advierte cuando detecta un posible valor de entrada que no maneja ninguna rama. El compilador no puede demostrar exhaustivamente cada combinación de patrones, pero este diagnóstico le ayuda a escribir código de coincidencia de patrones correcto. Para consultar reglas detalladas sobre coincidencia, inclusión y exhaustividad, consulte la referencia sobre patrones.
Prueba de una condición con is
Use el is operador cuando necesite una prueba booleana. El código siguiente evalúa la delivery expresión y aplica el patrón ExpressDelivery expressde declaración . La parte del tipo coincide cuando el valor evaluado no es NULL y su tipo de tiempo de ejecución es compatible con ExpressDelivery. Cuando el patrón coincide, su designación de variable declara express:
static void PrintTrackingCode(Delivery delivery)
{
if (delivery is ExpressDelivery express)
{
Console.WriteLine($"Track express package {express.TrackingCode}");
}
}
El compilador realiza un seguimiento de si se ha asignado una variable local antes de que el código lo lea. Este seguimiento se denomina asignación definitiva. Dentro del if bloque , la condición solo puede ser true cuando el patrón asignó el objeto coincidente a express. Por lo tanto, el compilador sabe que express está asignado definitivamente allí. El código puede usar su TrackingCode propiedad de forma segura. No necesitas hacer una conversión aparte. Si solo necesita la prueba de tipos y no necesita declarar una variable, use un patrón de tipo, como delivery is ExpressDelivery.
Use is null o is not null para comprobaciones nulas. Estos patrones no llaman a un operador != o == definido por el usuario.
static void PrintPackageStatus(Delivery? delivery)
{
if (delivery is null)
{
Console.WriteLine("No package is available.");
}
else
{
Console.WriteLine("A package is ready to track.");
}
}
Para obtener más instrucciones de seguridad nula, consulte Tipos de referencia que aceptan valores NULL.
Elegir entre una instrucción y una expresión
Los patrones funcionan con ambas formas de switch:
- Use una
switchinstrucción cuando cada coincidencia ejecute una o varias instrucciones. - Use una
switchexpresión cuando cada coincidencia debe generar un valor.
La siguiente instrucción switch indica una actualización sobre la entrega. La rama de entrega urgente escribe dos mensajes, por lo que una sentencia encaja de forma natural:
static void PrintDeliveryUpdate(Delivery? delivery)
{
switch (delivery)
{
case null:
Console.WriteLine("No delivery was scheduled.");
break;
case ExpressDelivery express:
Console.WriteLine($"Express delivery {express.TrackingCode} is ready.");
Console.WriteLine("Notify the priority desk.");
break;
case StandardDelivery standard:
Console.WriteLine($"Standard delivery arrives in {standard.Days} days.");
break;
default:
Console.WriteLine("Another delivery type is scheduled.");
break;
}
}
Cada case aplica un patrón a la expresión delivery. La sección de coincidencia puede ejecutar cualquier cantidad de instrucciones antes de que break salga del switch. La sección default se encarga de todo lo que no cubren los casos anteriores.
La siguiente expresión switch reemplaza una if / else if cadena que asigna un resultado:
static string GetStatusMessage(StandardDelivery delivery) =>
delivery.Days switch
{
0 => "Delivered today",
1 => "Arriving tomorrow",
<= 3 => "Arriving soon",
_ => "In transit"
};
Una expresión switch es concisa porque cada brazo tiene el mismo propósito: generar el valor devuelto. Use una instrucción switch cuando las ramas realicen acciones y use una expresión switch cuando las ramas calculen un resultado.
Categorías de patrones
C# incluye patrones para tipos comunes de pruebas de datos:
| Categoría de patrón | Qué prueba |
|---|---|
Declaración, constante y var patrones |
Un tipo en tiempo de ejecución, un valor constante específico o cualquier valor que desee capturar |
| Patrones de tipo | Un tipo en tiempo de ejecución sin declarar una variable |
| Patrones posicionales y de propiedad | Propiedades, campos o valores desestructurados |
| Patrones relacionales y lógicos | Comparaciones y combinaciones como and, ory not |
| Patrones de lista | Valores y forma de una lista o matriz |
| Descartar patrones y descartes | Cualquier valor restante o un valor que el código omita intencionadamente |
Los artículos Aspectos básicos vinculados en la tabla proporcionan cobertura centrada de las categorías documentadas actualmente en esta sección. Para obtener una sintaxis completa y ejemplos para todas las categorías de patrones, consulte la referencia de patrones.