Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym samouczku pokazano, jak używać dopasowywania wzorców do sprawdzania danych w języku C#. Piszesz małe ilości kodu, a następnie kompilujesz i uruchamiasz ten kod. Samouczek zawiera serię lekcji, które eksplorują różne rodzaje typów w języku C#. Te lekcje nauczą Cię podstaw języka C#.
Wskazówka
Gdy blok fragmentu kodu zawiera przycisk "Uruchom", ten przycisk otwiera okno interakcyjne lub zastępuje istniejący kod w oknie interaktywnym. Gdy fragment kodu nie zawiera przycisku "Uruchom", możesz skopiować kod i dodać go do bieżącego okna interaktywnego.
W poprzednich samouczkach przedstawiono wbudowane typy i typy, które definiujesz jako krotki lub rekordy. Wystąpienia tych typów można sprawdzić względem wzorca. To, czy wystąpienie jest zgodne ze wzorcem, określa akcje, które wykonuje program. W poniższych przykładach zauważysz ?
po nazwach typów. Ten symbol umożliwia, aby wartość tego typu mogła być null (na przykład wartość bool?
może być true
, false
lub null
). Aby uzyskać więcej informacji, zobacz Typy wartości dopuszczających null. Zacznijmy dowiedzieć się, jak można używać wzorców.
Dopasuj wartość
Wszystkie przykłady w tym samouczku wykorzystują dane tekstowe reprezentujące serię transakcji bankowych w formacie CSV (wartości rozdzielone przecinkami). W każdym z przykładów można dopasować rekord do wzorca przy użyciu is
wyrażenia lub switch
. Ten pierwszy przykład dzieli każdy wiersz na ,
znaku, a następnie pasuje do pierwszego pola ciągu względem wartości "DEPOZYT" lub "WYPŁATA" przy użyciu is
wyrażenia. Gdy jest on zgodny, kwota transakcji jest dodawana lub odliczana z bieżącego salda konta. Aby zobaczyć, jak działa, naciśnij przycisk "Uruchom":
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}");
}
}
Sprawdź dane wyjściowe. Zobaczysz, że każdy wiersz jest przetwarzany, porównując wartość tekstu w pierwszym polu. Poprzednia próbka może być podobnie skonstruowana przy użyciu operatora ==
celu przetestowania, czy dwie string
wartości są równe. Porównywanie zmiennej ze stałą jest podstawowym blokiem konstrukcyjnym do dopasowywania wzorców. Przyjrzyjmy się dokładniej blokom konstrukcyjnym, które są częścią dopasowywania wzorców.
Dopasowania wyliczenia
Kolejnym częstym zastosowaniem dopasowania do wzorca jest dopasowywanie wartości typu enum
. W następnym przykładzie są przetwarzane rekordy wejściowe, aby utworzyć krotkę , w której pierwsza wartość jest wartością enum
, która zwraca depozyt lub wypłatę. Druga wartość to wartość transakcji. Aby zobaczyć, jak działa, naciśnij przycisk "Uruchom":
Ostrzeżenie
Nie kopiuj i wklejaj. Aby uruchomić poniższe przykłady, należy zresetować okno interakcyjne. Jeśli popełnisz błąd, okno się zawiesza i musisz odświeżyć stronę, aby kontynuować.
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
}
W poprzednim przykładzie użyto if
również instrukcji do sprawdzenia wartości enum
wyrażenia. Inna forma dopasowywania wzorców używa switch
wyrażenia. Przyjrzyjmy się tej składni i sposobom jej używania.
Wyczerpujące dopasowania z switch
Seria instrukcji if
może przetestować serię warunków. Jednak kompilator nie może stwierdzić, czy seria instrukcji if
jest wyczerpująca , czy późniejsze if
warunki są subsumowane przez wcześniejsze warunki. Wyrażenie switch
zapewnia spełnienie obu tych cech, co skutkuje mniejszą liczbą usterek w aplikacjach. Wypróbujmy to i poeksperymentujmy. Skopiuj następujący kod. W oknie interaktywnym zastąp dwie instrukcje if
skopiowanym wyrażeniem switch
. Po zmodyfikowaniu kodu naciśnij przycisk "Uruchom" w górnej części okna interaktywnego, aby uruchomić nowy przykład.
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
(TransactionType.Withdrawal, var amount) => -amount,
_ => 0.0,
};
Po uruchomieniu kodu zobaczysz, że działa on tak samo. Aby zademonstrować podsumpcję, zmień kolejność ramion przełącznika, jak pokazano w poniższym fragmencie kodu:
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
_ => 0.0,
(TransactionType.Withdrawal, var amount) => -amount,
};
Po zmianie kolejności ramion przełącznika naciśnij przycisk "Uruchom". Kompilator zgłasza błąd, ponieważ ramię z _
pasuje do każdej wartości. W rezultacie to ostatnie ramię z TransactionType.Withdrawal
nigdy nie działa. Kompilator informuje, że coś jest nie tak w kodzie.
Kompilator wydaje ostrzeżenie, jeśli wyrażenie przetestowane w wyrażeniu switch
może zawierać wartości, które nie pasują do żadnego ramienia przełącznika. Jeśli niektóre wartości mogą nie być zgodne z dowolnym warunkiem, switch
wyrażenie nie jest wyczerpujące. Kompilator wyświetla również ostrzeżenie, jeśli niektóre wartości danych wejściowych nie pasują do żadnego z ramion przełącznika. Jeśli na przykład usuniesz wiersz z parametrem _ => 0.0,
, wszystkie nieprawidłowe wartości nie są zgodne. W czasie wykonywania to się nie powiedzie. Po zainstalowaniu zestawu .NET SDK i kompilowania programów w środowisku możesz przetestować to zachowanie. Środowisko online nie wyświetla ostrzeżeń w oknie danych wyjściowych.
Wzorce typów
Aby ukończyć ten samouczek, przyjrzyjmy się jeszcze jednemu blokowi konstrukcyjnemu do dopasowywania wzorców: wzorcowi typu.
Wzorzec typu testuje wyrażenie w czasie wykonywania, aby sprawdzić, czy jest to określony typ. Możesz użyć testu typu z wyrażeniem is
lub wyrażeniem switch
. Zmodyfikujmy bieżący przykład na dwa sposoby. Najpierw, zamiast krotki, skompilujmy Deposit
i Withdrawal
typy rekordów reprezentujące transakcje. Dodaj następujące deklaracje w dolnej części okna interaktywnego:
public record Deposit(double Amount, string description);
public record Withdrawal(double Amount, string description);
Następnie dodaj tę metodę po metodzie Main
, aby przeanalizować tekst i zwrócić serię rekordów:
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;
}
}
Na koniec zastąp pętlę foreach
w metodzie Main
następującym kodem:
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}");
}
Następnie naciśnij przycisk "Uruchom", aby wyświetlić wyniki. Ta ostateczna wersja testuje dane wejściowe względem typu.
Dopasowanie wzorca zapewnia słownictwo do porównywania wyrażenia z cechami. Wzorce mogą zawierać typ wyrażenia, wartości typów, wartości właściwości i ich kombinacje. Porównywanie wyrażeń ze wzorcem może być bardziej przejrzyste niż wiele if
porównań. Poznaliśmy niektóre wzorce, których można użyć do dopasowywania wyrażeń. Istnieje wiele innych sposobów używania dopasowywania wzorców w aplikacjach. Najpierw odwiedź witrynę platformy .NET , aby pobrać zestaw .NET SDK, utworzyć projekt na maszynie i kontynuować kodowanie. Podczas eksplorowania możesz dowiedzieć się więcej na temat dopasowywania wzorców w języku C# w następujących artykułach:
- dopasowywanie wzorca w języku C#
- Eksplorowanie samouczka dopasowywania wzorców
- Scenariusz dopasowywania wzorców