Nota
L'accés a aquesta pàgina requereix autorització. Podeu provar d'iniciar la sessió o de canviar els directoris.
L'accés a aquesta pàgina requereix autorització. Podeu provar de canviar els directoris.
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#. Comience con la descripción general de la coincidencia de patrones si no está familiarizado con los patrones. Para obtener reglas de lenguaje completas, consulte patrones de propiedades y patrones posicionales en la referencia del lenguaje.
Los patrones de propiedades y los patrones posicionales comprueban partes de un valor. La diferencia es cómo identifican esas partes:
- Un patrón de propiedad asigna un nombre a las propiedades o campos que se van a probar.
- Un patrón posicional identifica los valores por su orden.
Una deconstrucción expone un conjunto ordenado de valores de componente. Una tupla ya tiene un orden de elementos; consulte descomponer tuplas. Para otro tipo, un Deconstruct método define qué valores de componente se exponen y su orden.
Comparación de nombres y posiciones
El siguiente patrón de propiedad comprueba dos propiedades con nombre explícito de una medición meteorológica, con valores de temperatura en grados Celsius:
static bool IsHotAndHumid(WeatherReading reading) =>
reading is { TemperatureC: > 30, HumidityPercent: > 70 };
sealed record WeatherReading(int TemperatureC, int HumidityPercent);
El siguiente patrón posicional prueba un valor de señal seguido de un valor booleano:
static string GetCrossingInstruction(
PedestrianSignal signal, bool crossingIsClear) =>
(signal, crossingIsClear) switch
{
(PedestrianSignal.Walk, true) => "Cross now",
(PedestrianSignal.Walk, false) => "Wait for the crossing to clear",
_ => "Wait for the walk signal"
};
enum PedestrianSignal
{
Stop,
Walk
}
El patrón de propiedad identifica sus entradas por los nombres TemperatureC y HumidityPercent. El código de cruce crea una tupla a partir de los valores independientes crossingIsClear y signal. A continuación, el patrón de tupla identifica esos valores por orden: signal primero y crossingIsClear segundo. Un patrón posicional es una buena opción porque esta tupla recién creada tiene solo dos valores y su orden tiene un significado claro en la decisión de cruce.
Elija un patrón de propiedad cuando los nombres de los miembros ayuden a explicar la comprobación. Los patrones de propiedad suelen ser más claros para las clases, estructuras y registros. Elija un patrón posicional cuando el orden ya proporcione a los valores un significado obvio. Los patrones posicionales son más útiles con tuplas, que combinan varios valores relacionados en un único valor ordenado de forma fija.
Siga las entradas anidadas en patrones recursivos.
Los patrones de propiedad y posición son patrones recursivos: aplican otro patrón a cada propiedad, campo o posición que seleccionan. El valor seleccionado se convierte en la entrada de ese patrón anidado.
En IsHotAndHumid, reading es la expresión de entrada del patrón de propiedad. C# evalúa esa expresión antes de realizar la coincidencia. El patrón obtiene dos valores del objeto resultante:
- El patrón
> 30relacional comprueba el valor deTemperatureC. - El patrón
> 70relacional comprueba el valor deHumidityPercent.
Una comprobación externa de tipo es opcional, y las cláusulas de patrón recursivas pueden estar vacías. Por ejemplo, el patrón { } de propiedad vacío coincide con cualquier valor evaluado que no sea NULL.
Los patrones de propiedad y posición solo coinciden con valores evaluados que no son NULL. Cuando null forma parte del dominio de entrada, elija primero un patrón recursivo que compruebe un valor distinto de NULL:
static string DescribeNullableInput(object? value)
{
if (value is not { } nonNullValue)
{
return "No value";
}
return nonNullValue switch
{
DateTime => "Date",
string => "Text",
_ => "Another type"
};
}
La expresión de entrada es value. C# lo evalúa y el { } patrón de propiedad prueba el valor resultante para que no sea NULL antes de asignarlo a nonNullValue. A continuación, la siguiente expresión switch puede probar varios tipos de tiempo de ejecución posibles. Sus DateTime patrones de tipo y string no tienen ninguna designación porque el método solo necesita identificar cada tipo, no capturar su valor.
Cuando las cláusulas de patrones recursivos contienen patrones anidados, cada propiedad, cada campo o cada posición seleccionada pasa a ser la entrada de su patrón anidado.
Puede agregar una prueba de tipo antes de las llaves cuando la expresión de entrada pueda generar tipos diferentes. También puede usar una ruta de acceso de miembro para probar una propiedad anidada:
static string DescribeDate(object? value) =>
value switch
{
DateTime { Date.DayOfWeek:
DayOfWeek.Saturday or DayOfWeek.Sunday } => "Weekend date",
DateTime => "Weekday date",
null => "No date",
_ => "Not a date"
};
value es la expresión de entrada. C# lo evalúa primero y comprueba si el valor resultante es .DateTime A continuación, el valor de la propiedad Date pasa a ser la entrada para el acceso al miembro DayOfWeek. Por último, el DayOfWeek valor se convierte en la entrada en el patrón lógico que prueba dos constantes. La coincidencia se produce correctamente cuando el valor externo tiene el tipo especificado y ninguno de los objetos necesarios a lo largo de la ruta de acceso al miembro es nulo.
Comparación de patrones con instrucciones de bifurcación
El método anterior DescribeDate expresa cuatro resultados como patrones:
static string DescribeDate(object? value) =>
value switch
{
DateTime { Date.DayOfWeek:
DayOfWeek.Saturday or DayOfWeek.Sunday } => "Weekend date",
DateTime => "Weekday date",
null => "No date",
_ => "Not a date"
};
El método siguiente genera los mismos resultados con una serie de instrucciones de bifurcación imperativas:
static string DescribeDateWithBranches(object? value)
{
if (value is DateTime date)
{
if (date.DayOfWeek == DayOfWeek.Saturday ||
date.DayOfWeek == DayOfWeek.Sunday)
{
return "Weekend date";
}
return "Weekday date";
}
if (value is null)
{
return "No date";
}
return "Not a date";
}
La versión basada en patrones mantiene los resultados posibles juntos cuando varias ramas prueban el tipo y la forma de un valor. La versión imperativa hace explícito cada paso de comprobación y retorno. Para una condición, cualquiera de los formularios podría tener un aspecto similar. A medida que crece el número de ramas relacionadas, los patrones pueden facilitar la comparación de las alternativas.