Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В этом руководстве описано, как использовать сопоставление шаблонов для проверки данных в C#. Вы пишете небольшие объемы кода, а затем компилируете и запускаете этот код. В этом руководстве содержится ряд уроков, которые изучают различные типы шаблонов, поддерживаемых C#. Эти уроки учат вас основам языка C#.
Изучив это руководство, вы:
- Запустите пространство кода GitHub с помощью среды разработки C#.
- Тестируйте данные для дискретных значений.
- Соотносить перечисляемые данные со значением.
- Создайте исчерпывающие совпадения с помощью
switchвыражений. - Сопоставление типов с использованием шаблонов типов.
Предпосылки
У вас должно быть одно из следующих элементов:
- Учетная запись GitHub для использования GitHub Codespaces. Если у вас еще нет учетной записи, вы можете создать бесплатную учетную запись на GitHub.com.
- Компьютер со следующими инструментами:
Сопоставление значения
В предыдущих руководствах показаны встроенные типы и типы, которые определяются как кортежи или записи. Вы можете проверить экземпляры этих типов на соответствие шаблону. Совпадает ли экземпляр с шаблоном, определяет действия, выполняемые программой. В приведенных ниже примерах вы увидите ? после имен типов. Этот символ позволяет значению этого типа иметь значение NULL (например, bool? может быть true, falseили null). Дополнительные сведения см. в разделе "Типы значений, допускающих значение NULL". Начнем с изучения способа использования шаблонов.
Откройте окно браузера в пространствах кода GitHub. Создайте новое пространство кода из шаблона .NET. Если вы выполнили другие уроки в этой серии, вы можете открыть это кодовое пространство.
При загрузке пространства кода создайте новый файл в папке учебников с именем patterns.cs.
Откройте новый файл.
Во всех примерах в этом руководстве используются текстовые входные данные, представляющие ряд банковских транзакций в виде входных данных, разделенных запятыми (CSV). В каждом из образцов каждую запись можно сопоставить с шаблоном с помощью выражения
isилиswitch. Этот первый пример разбивает каждую строку на,символ, а затем сопоставляет первое строковое поле со значением "ДЕПОЗИТ" или "ВЫВОД" с помощьюisвыражения. При совпадении сумма транзакции добавляется или вычитается из текущего баланса счета. Чтобы увидеть его работу, добавьте следующий код в patterns.cs: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}"); } }Затем введите следующий текст в окне терминала:
cd tutorials dotnet patterns.csПроверьте выходные данные. Вы можете увидеть, что каждая строка обрабатывается, сравнивая значение текста в первом поле.
Можно аналогично создать предыдущий пример с помощью == оператора для проверки того, что два string значения равны. Сравнение переменной с константой является основным стандартным блоком для сопоставления шаблонов. Давайте рассмотрим больше основных элементов, которые являются частью сопоставления шаблонов.
Совпадения элементов перечисления
Другой распространенный способ сопоставления шаблонов — сопоставление значений enum типа. Следующий пример обрабатывает входные записи, чтобы создать кортеж, где первое значение является enum значением, которое отмечает депозит или вывод. Второе значение — это значение транзакции.
Добавьте следующий код в конец исходного файла. Он определяет перечисление
TransactionType:public enum TransactionType { Deposit, Withdrawal, Invalid }Добавьте функцию для анализа банковской транзакции в кортеж, содержащий тип транзакции и значение транзакции. Добавьте следующий код перед объявлением
TransactionTypeперечисления: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); } } }Добавьте новый цикл для обработки данных транзакции с помощью вами объявленного перечисления
TransactionType.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}"); }
В предыдущем примере также используется if инструкция для проверки значения enum выражения. Другая форма сопоставления шаблонов использует switch выражение. Давайте рассмотрим этот синтаксис и как его можно использовать.
Исчерпывающие совпадения с switch
Ряд if инструкций может протестировать ряд условий. Но компилятор не может определить, являются ли ряд операторов ifисчерпывающими, или если более поздние if условия охвачены предыдущими условиями.
Исчерпывающим образом означает, что один из ifelse предложений в серии тестов обрабатывает все возможные входные данные. Если ряд инструкций if является исчерпывающим, все возможные входные данные удовлетворяют по крайней мере одному if или else предложению.
Подстановочное правило означает, что позднее if или else условие не может быть достигнуто, так как предыдущие if или else условия соответствуют всем возможным входным данным. Например, в следующем примере кода одно предложение никогда не совпадает:
int n = GetNumber();
if (n < 20)
Console.WriteLine("n is less than 20");
else if (n < 10)
Console.WriteLine("n is less than 10"); // unreachable
else
Console.WriteLine("n is greater than 20");
Условие else if никогда не выполняется, так как любое число меньше 10 также меньше 20. Выражение switch гарантирует выполнение обоих этих характеристик, что приводит к меньшим ошибкам в приложениях. Давайте попробуем и поэкспериментируем.
Скопируйте следующий код. Замените две инструкции
ifв вашемforeachцикле на скопированное выражениеswitch.currentBalance += transaction switch { (TransactionType.Deposit, var amount) => amount, (TransactionType.Withdrawal, var amount) => -amount, _ => 0.0, };Введите
dotnet patterns.csв окне терминала, чтобы запустить новый пример.При запуске кода вы увидите, что он работает так же.
Чтобы продемонстрировать подсумпцию, переставьте ветви переключателя, как показано в следующем фрагменте:
currentBalance += transaction switch { (TransactionType.Deposit, var amount) => amount, _ => 0.0, (TransactionType.Withdrawal, var amount) => -amount, };После переупорядочивания рычагов переключателя введите
dotnet patterns.csв окне терминала. Компилятор выдает ошибку, потому что ветвь с_совпадает с каждым возможным значением. В результате, этот последний сегмент сTransactionType.Withdrawalникогда не выполняется. Компилятор сообщает, что в коде что-то не так.Компилятор выдает предупреждение, если выражение, проверенное в
switchвыражении, может содержать значения, которые не соответствуют ни одной ветви switch. Если некоторые значения не могут соответствовать любому условию,switchвыражение не является исчерпывающим. Компилятор также выдает предупреждение, если некоторые значения входных данных не соответствуют ни одной из ветвей оператора switch.Удалите строку с
_ => 0.0,, чтобы недопустимые значения не совпадали.Введите
dotnet patterns.cs, чтобы просмотреть результаты.Компилятор выдает предупреждение. Тестовые данные допустимы, поэтому программа работает. Однако любые недопустимые данные могут привести к сбою во время выполнения.
Шаблоны типов
Для завершения работы с этим руководством изучите еще один стандартный блок для сопоставления шаблонов: типовой шаблон.
Шаблон типа проверяет выражение во время выполнения, чтобы узнать, является ли он указанным типом. С выражением is или switch выражением можно использовать тест типа. Измените текущий пример двумя способами. Во-первых, вместо кортежа создайте типы записей Deposit и Withdrawal, которые представляют транзакции.
Добавьте следующие объявления в конце файла кода:
public record Deposit(double Amount, string description); public record Withdrawal(double Amount, string description);Добавьте этот метод непосредственно перед объявлением
TransactionTypeперечисления. Он анализирует текст и возвращает ряд записей: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; } }Добавьте следующий код после последнего
foreachцикла:currentBalance = 0.0; 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}"); }Введите
dotnet patterns.csв окне терминала, чтобы увидеть результаты. Эта окончательная версия проверяет входные данные по типу.
Сопоставление шаблонов предоставляет словарь для сравнения выражения с характеристиками. Шаблоны могут включать тип выражения, значения типов, значений свойств и сочетаний этих выражений. Сравнение выражений с шаблоном может быть более четким, чем несколько if сравнений. Вы изучили некоторые шаблоны, которые можно использовать для сопоставления выражений. Существует множество способов использования сопоставления шаблонов в приложениях. При изучении вы можете узнать больше о сопоставлении шаблонов в C# в следующих статьях:
- Сопоставление шаблонов в C#
- Изучение руководства по сопоставлению шаблонов
- Сценарий сопоставления шаблонов
Очистка ресурсов
GitHub автоматически удаляет пространство Codespace через 30 дней бездействия. Вы завершили все уроки в этой серии. Чтобы удалить ваш Codespace, откройте окно браузера и перейдите к вашим Codespaces. В окне отобразится список ваших codespaces. Выберите три точки (...) в записи для пространства кода учебника для обучения и выберите удалить.
Связанный контент
- Скачайте и установите пакет SDK для .NET 10.
- Скачайте и установите Visual Studio Code.
- Скачайте и установите C# DevKit.
- Ознакомьтесь с разделом основы C# , чтобы узнать больше о C#.