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.
En este tutorial se explica cómo usar la coincidencia de patrones para inspeccionar los datos en C#. Puede escribir pequeñas cantidades de código y, a continuación, compilar y ejecutar ese código. El tutorial contiene una serie de lecciones que exploran diferentes tipos de tipos en C#. Estas lecciones le enseñan los aspectos básicos del lenguaje C#.
Sugerencia
Cuando un bloque de fragmento de código incluye el botón "Ejecutar", ese botón abre la ventana interactiva o reemplaza el código existente en la ventana interactiva. Cuando el fragmento de código no incluye un botón "Ejecutar", puede copiar el código y agregarlo a la ventana interactiva actual.
En los tutoriales anteriores se demostraron los tipos integrados y los tipos que se definen como tuplas o registros. Las instancias de estos tipos se pueden comprobar con un patrón. Si una instancia coincide con un patrón determina las acciones que realiza el programa. En los ejemplos siguientes, observará ?
después de los nombres de tipo. Este símbolo permite que el valor de este tipo sea NULL (por ejemplo, bool?
puede ser true
, false
o null
). Para obtener más información, consulte Tipos de valor anulable. Comencemos a explorar cómo puede usar patrones.
Igualar un valor
Todos los ejemplos de este tutorial usan la entrada de texto que representa una serie de transacciones bancarias como entrada de valores separados por comas (CSV). En cada una de las muestras, puede hacer coincidir el registro con un patrón utilizando una expresión de is
o de switch
. En este primer ejemplo, cada línea se divide en el carácter ,
, y luego se compara el primer campo de cadena con el valor "DEPOSIT" o "WITHDRAWAL" utilizando una expresión is
. Cuando coincide, el importe de la transacción se agrega o deduce del saldo de la cuenta actual. Para ver que funciona, presione el botón "Ejecutar":
string bankRecords = """
DEPOSIT, 10000, Initial balance
DEPOSIT, 500, regular deposit
WITHDRAWAL, 1000, rent
DEPOSIT, 2000, freelance payment
WITHDRAWAL, 300, groceries
DEPOSIT, 700, gift from friend
WITHDRAWAL, 150, utility bill
DEPOSIT, 1200, tax refund
WITHDRAWAL, 500, car maintenance
DEPOSIT, 400, cashback reward
WITHDRAWAL, 250, dining out
DEPOSIT, 3000, bonus payment
WITHDRAWAL, 800, loan repayment
DEPOSIT, 600, stock dividends
WITHDRAWAL, 100, subscription fee
DEPOSIT, 1500, side hustle income
WITHDRAWAL, 200, fuel expenses
DEPOSIT, 900, refund from store
WITHDRAWAL, 350, shopping
DEPOSIT, 2500, project milestone payment
WITHDRAWAL, 400, entertainment
""";
double currentBalance = 0.0;
var reader = new StringReader(bankRecords);
string? line;
while ((line = reader.ReadLine()) is not null)
{
if (string.IsNullOrWhiteSpace(line)) continue;
// Split the line based on comma delimiter and trim each part
string[] parts = line.Split(',');
string? transactionType = parts[0]?.Trim();
if (double.TryParse(parts[1].Trim(), out double amount))
{
// Update the balance based on transaction type
if (transactionType?.ToUpper() is "DEPOSIT")
currentBalance += amount;
else if (transactionType?.ToUpper() is "WITHDRAWAL")
currentBalance -= amount;
Console.WriteLine($"{line.Trim()} => Parsed Amount: {amount}, New Balance: {currentBalance}");
}
}
Examine la salida. Puede ver que cada línea se procesa comparando el valor del texto en el primer campo. El ejemplo anterior podría construirse de forma similar mediante el ==
operador para probar que dos string
valores son iguales. Comparar una variable con una constante es uno de los bloques básicos para la coincidencia de patrones. Vamos a explorar más de los bloques de construcción que forman parte de la coincidencia de patrones.
Coincidencias de enum
Otro uso común para la coincidencia de patrones es coincidir con los valores de un enum
tipo. En este ejemplo siguiente se procesan los registros de entrada para crear una tupla donde el primer valor es un enum
valor que anota un depósito o una retirada. El segundo valor es el valor de la transacción. Para ver que funciona, presione el botón "Ejecutar":
Advertencia
No copie y pegue. La ventana interactiva debe restablecerse para ejecutar los ejemplos siguientes. Si comete un error, la ventana se bloquea y necesita actualizar la página para continuar.
public static class ExampleProgram
{
const string bankRecords = """
DEPOSIT, 10000, Initial balance
DEPOSIT, 500, regular deposit
WITHDRAWAL, 1000, rent
DEPOSIT, 2000, freelance payment
WITHDRAWAL, 300, groceries
DEPOSIT, 700, gift from friend
WITHDRAWAL, 150, utility bill
DEPOSIT, 1200, tax refund
WITHDRAWAL, 500, car maintenance
DEPOSIT, 400, cashback reward
WITHDRAWAL, 250, dining out
DEPOSIT, 3000, bonus payment
WITHDRAWAL, 800, loan repayment
DEPOSIT, 600, stock dividends
WITHDRAWAL, 100, subscription fee
DEPOSIT, 1500, side hustle income
WITHDRAWAL, 200, fuel expenses
DEPOSIT, 900, refund from store
WITHDRAWAL, 350, shopping
DEPOSIT, 2500, project milestone payment
WITHDRAWAL, 400, entertainment
""";
public static void Main()
{
double currentBalance = 0.0;
foreach (var transaction in TransactionRecords(bankRecords))
{
if (transaction.type == TransactionType.Deposit)
currentBalance += transaction.amount;
else if (transaction.type == TransactionType.Withdrawal)
currentBalance -= transaction.amount;
Console.WriteLine($"{transaction.type} => Parsed Amount: {transaction.amount}, New Balance: {currentBalance}");
}
}
static IEnumerable<(TransactionType type, double amount)> TransactionRecords(string inputText)
{
var reader = new StringReader(inputText);
string? line;
while ((line = reader.ReadLine()) is not null)
{
string[] parts = line.Split(',');
string? transactionType = parts[0]?.Trim();
if (double.TryParse(parts[1].Trim(), out double amount))
{
// Update the balance based on transaction type
if (transactionType?.ToUpper() is "DEPOSIT")
yield return (TransactionType.Deposit, amount);
else if (transactionType?.ToUpper() is "WITHDRAWAL")
yield return (TransactionType.Withdrawal, amount);
}
else {
yield return (TransactionType.Invalid, 0.0);
}
}
}
}
public enum TransactionType
{
Deposit,
Withdrawal,
Invalid
}
En el ejemplo anterior también se usa una if
instrucción para comprobar el valor de una enum
expresión. Otra forma de coincidencia de patrones usa una switch
expresión. Vamos a explorar esa sintaxis y cómo se puede usar.
Coincidencias exhaustivas con switch
Una serie de if
instrucciones puede probar una serie de condiciones. Pero el compilador no puede saber si una serie de if
instrucciones son exhaustivas o si las if
condiciones posteriores se subsumen en condiciones anteriores. La switch
expresión garantiza que se cumplen ambas características, lo que produce menos errores en las aplicaciones. Vamos a probarlo y veamos qué pasa. Copie el código siguiente. Reemplaza las dos expresiones if
de la ventana interactiva por la instrucción switch
que copiaste. Después de modificar el código, presione el botón "Ejecutar" en la parte superior de la ventana interactiva para ejecutar el nuevo ejemplo.
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
(TransactionType.Withdrawal, var amount) => -amount,
_ => 0.0,
};
Al ejecutar el código, verá que funciona igual. Para demostrar la subsumpción, reordene las ramas del interruptor como se muestra en el siguiente fragmento de código.
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
_ => 0.0,
(TransactionType.Withdrawal, var amount) => -amount,
};
Después de reordenar los brazos del conmutador, presione el botón "Ejecutar". El compilador emite un error porque el brazo con _
coincide con cada valor. Como resultado, ese brazo final con TransactionType.Withdrawal
nunca se ejecuta. El compilador le indica que algo está mal en el código.
El compilador emite una advertencia si la expresión probada en una switch
expresión podría contener valores que no coinciden con ningún brazo de conmutador. Si algunos valores podrían no coincidir con ninguna condición, la switch
expresión no es exhaustiva. El compilador también emite una advertencia si algunos valores de la entrada no coinciden con ninguno de los brazos switch. Por ejemplo, si quita la línea con _ => 0.0,
, los valores no válidos no coinciden. En tiempo de ejecución, se produciría un error. Una vez que instale el SDK de .NET y compile programas en su entorno, puede probar este comportamiento. La experiencia en línea no muestra advertencias en la ventana de salida.
Patrones de tipo
Para finalizar este tutorial, exploremos un bloque más de construcción para la coincidencia de patrones: el patrón de tipo. Un patrón de tipo prueba una expresión en tiempo de ejecución para ver si es el tipo especificado. Puede usar una prueba de tipo con una is
expresión o una switch
expresión. Vamos a modificar el ejemplo actual de dos maneras. En primer lugar, en lugar de una tupla, vamos a construir tipos de registro Deposit
y Withdrawal
que representan las transacciones. Agregue las siguientes declaraciones en la parte inferior de la ventana interactiva:
public record Deposit(double Amount, string description);
public record Withdrawal(double Amount, string description);
A continuación, agregue este método después del Main
método para analizar el texto y devolver una serie de registros:
public static IEnumerable<object?> TransactionRecordType(string inputText)
{
var reader = new StringReader(inputText);
string? line;
while ((line = reader.ReadLine()) is not null)
{
string[] parts = line.Split(',');
string? transactionType = parts[0]?.Trim();
if (double.TryParse(parts[1].Trim(), out double amount))
{
// Update the balance based on transaction type
if (transactionType?.ToUpper() is "DEPOSIT")
yield return new Deposit(amount, parts[2]);
else if (transactionType?.ToUpper() is "WITHDRAWAL")
yield return new Withdrawal(amount, parts[2]);
}
yield return default;
}
}
Por último, reemplace el foreach
bucle en el Main
método por el código siguiente:
foreach (var transaction in TransactionRecordType(bankRecords))
{
currentBalance += transaction switch
{
Deposit d => d.Amount,
Withdrawal w => -w.Amount,
_ => 0.0,
};
Console.WriteLine($" {transaction} => New Balance: {currentBalance}");
}
A continuación, presione el botón "Ejecutar" para ver los resultados. Esta versión final prueba la entrada contra un tipo.
La coincidencia de patrones proporciona un vocabulario para comparar una expresión con las características. Los patrones pueden incluir el tipo de la expresión, los valores de los tipos, los valores de propiedad y las combinaciones de ellas. Comparar expresiones con un patrón puede ser más claro que varias if
comparaciones. Ha explorado algunos de los patrones que puede usar para hacer coincidir expresiones. Hay muchas más maneras de usar la coincidencia de patrones en las aplicaciones. En primer lugar, visite el sitio de .NET para descargar el SDK de .NET, crear un proyecto en la máquina y seguir codificando. A medida que explore, puede obtener más información sobre la coincidencia de patrones en C# en los siguientes artículos: