Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce tutoriel vous explique comment utiliser la correspondance de modèle pour inspecter les données en C#. Vous écrivez de petites quantités de code, puis vous compilez et exécutez ce code. Le tutoriel contient une série de leçons qui explorent différents types de types en C#. Ces leçons vous enseignent les principes fondamentaux de la langue C#.
Conseil / Astuce
Lorsqu’un bloc d’extrait de code inclut le bouton « Exécuter », ce bouton ouvre la fenêtre interactive ou remplace le code existant dans la fenêtre interactive. Lorsque l’extrait de code n’inclut pas de bouton « Exécuter », vous pouvez copier le code et l’ajouter à la fenêtre interactive active.
Les didacticiels précédents ont montré les types intégrés et ceux que vous définissez sous forme de tuples ou d'enregistrements. Les instances de ces types peuvent être vérifiées par rapport à un modèle. Si une instance correspond à un modèle détermine les actions effectuées par votre programme. Dans les exemples ci-dessous, vous remarquerez ?
après les noms de type. Ce symbole permet à la valeur de ce type d’être null (par exemple, bool?
peut être true
, false
ou null
). Pour plus d'informations, consultez types de valeur nullables. Commençons à explorer la façon dont vous pouvez utiliser des modèles.
Mettre en correspondance une valeur
Tous les exemples de ce didacticiel utilisent une entrée de texte qui représente une série de transactions bancaires sous forme d’entrée de valeurs séparées par des virgules (CSV). Dans chacun des exemples, vous pouvez faire correspondre l’enregistrement à un schéma en utilisant soit une expression is
soit une expression switch
. Ce premier exemple fractionne chaque ligne au niveau du caractère ,
, puis fait correspondre le premier champ de texte à la valeur « DEPOSIT » ou « WITHDRAWAL » à l'aide d'une expression . Lorsqu’il correspond, le montant de la transaction est ajouté ou déduit du solde du compte actuel. Pour le voir fonctionner, appuyez sur le bouton « Exécuter » :
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}");
}
}
Examinez le résultat. Vous pouvez voir que chaque ligne est traitée en comparant la valeur du texte dans le premier champ. L’exemple précédent peut être construit de la même façon à l’aide de l’opérateur ==
pour tester que deux string
valeurs sont égales. La comparaison d’une variable à une constante est un bloc de construction de base pour la mise en correspondance des modèles. Examinons davantage les blocs de construction qui font partie de la mise en correspondance des modèles.
Correspondances d’énumération
Une autre utilisation courante de la correspondance de modèle consiste à mettre en correspondance les valeurs d'un enum
type. Cet exemple traite ensuite les enregistrements d’entrée pour créer un tuple où la première valeur est une enum
valeur qui note un dépôt ou un retrait. La deuxième valeur est la valeur de la transaction. Pour le voir fonctionner, appuyez sur le bouton « Exécuter » :
Avertissement
Ne pas copier-coller. La fenêtre interactive doit être réinitialisée pour exécuter les exemples suivants. Si vous faites une erreur, la fenêtre se bloque et vous devez actualiser la page pour continuer.
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
}
L’exemple précédent utilise également une if
instruction pour vérifier la valeur d’une enum
expression. Une autre forme de correspondance de modèle utilise une switch
expression. Examinons cette syntaxe et la façon dont vous pouvez l’utiliser.
Correspondances exhaustives avec switch
Une série d’instructions if
peut tester une série de conditions. Toutefois, le compilateur ne peut pas savoir si une série d’instructions if
est exhaustive ou si des conditions if
sont subordonnées par des conditions antérieures. L’expression switch
garantit que ces deux caractéristiques sont remplies, ce qui entraîne moins de bogues dans vos applications. Essayons-le et expérimentons. Copiez le code suivant. Remplacez les deux if
instructions de la fenêtre interactive par l’expression switch
que vous avez copiée. Une fois que vous avez modifié le code, appuyez sur le bouton « Exécuter » en haut de la fenêtre interactive pour exécuter le nouvel exemple.
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
(TransactionType.Withdrawal, var amount) => -amount,
_ => 0.0,
};
Lorsque vous exécutez le code, vous voyez qu’il fonctionne de la même façon. Pour illustrer la sous-énumération, réorganisez les bras de commutateur comme indiqué dans l’extrait de code suivant :
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
_ => 0.0,
(TransactionType.Withdrawal, var amount) => -amount,
};
Après avoir réorganisé les bras de commutateur, appuyez sur le bouton « Exécuter ». Le compilateur émet une erreur, car le bras avec _
correspond à chaque valeur. Par conséquent, ce bras final avec TransactionType.Withdrawal
ne s’exécute jamais. Le compilateur vous indique que quelque chose ne va pas dans votre code.
Le compilateur émet un avertissement si l’expression testée dans une switch
expression peut contenir des valeurs qui ne correspondent à aucun bras de commutateur. Si certaines valeurs peuvent ne pas correspondre à une condition, l’expression switch
n’est pas exhaustive. Le compilateur émet également un avertissement si certaines valeurs de l’entrée ne correspondent pas aux bras de commutateur. Par exemple, si vous supprimez la ligne avec _ => 0.0,
, les valeurs non valides ne correspondent pas. Au moment de l’exécution, cela échouerait. Une fois que vous avez installé le Kit de développement logiciel (SDK) .NET et généré des programmes dans votre environnement, vous pouvez tester ce comportement. L’expérience en ligne n’affiche pas d’avertissements dans la fenêtre de sortie.
Modèles de type
Pour terminer ce tutoriel, nous allons explorer un autre élément constitutif de la correspondance de motifs : le modèle de type. Un modèle de type teste une expression au moment de l’exécution pour voir s’il s’agit du type spécifié. Vous pouvez utiliser un test de type avec une is
expression ou une switch
expression. Modifions l’exemple actuel de deux façons. Tout d’abord, au lieu d’un tuple, nous allons générer Deposit
et Withdrawal
enregistrer des types qui représentent les transactions. Ajoutez les déclarations suivantes en bas de la fenêtre interactive :
public record Deposit(double Amount, string description);
public record Withdrawal(double Amount, string description);
Ensuite, ajoutez cette méthode après la Main
méthode pour analyser le texte et renvoyer une série d’enregistrements :
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;
}
}
Enfin, remplacez la foreach
boucle dans la Main
méthode par le code suivant :
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}");
}
Ensuite, appuyez sur le bouton « Exécuter » pour afficher les résultats. Cette version finale teste l’entrée par rapport à un type.
La mise en correspondance des modèles fournit un vocabulaire pour comparer une expression par rapport aux caractéristiques. Les modèles peuvent inclure le type, les valeurs des types, les valeurs des propriétés et les combinaisons d’expressions. La comparaison d’expressions par rapport à un modèle peut être plus claire que plusieurs if
comparaisons. Vous avez exploré certains des modèles que vous pouvez utiliser pour faire correspondre des expressions. Il existe de nombreuses façons d’utiliser la correspondance de modèles dans vos applications. Tout d’abord, visitez le site .NET pour télécharger le Kit de développement logiciel (SDK) .NET, créez un projet sur votre ordinateur et continuez à coder. À mesure que vous explorez, vous pouvez en savoir plus sur la correspondance des modèles en C# dans les articles suivants :