Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве описано, как использовать сопоставление шаблонов для проверки данных в C#. Вы пишете небольшие объемы кода, а затем компилируете и запускаете этот код. В этом руководстве содержится ряд уроков, которые изучают различные типы типов в C#. Эти уроки учат вас основам языка C#.
Подсказка
Если блок фрагмента кода включает кнопку "Выполнить", эта кнопка открывает интерактивное окно или заменяет существующий код в интерактивном окне. Если фрагмент не содержит кнопку "Выполнить", можно скопировать код и добавить его в текущее интерактивное окно.
В предыдущих руководствах показаны встроенные типы и типы, которые определяются как кортежи или записи. Экземпляры этих типов можно проверить на соответствие шаблону. Совпадает ли экземпляр с шаблоном, определяет действия, выполняемые программой. В приведенных ниже примерах вы заметите ?
после имен типов. Этот символ позволяет значению этого типа иметь значение NULL (например, bool?
может быть true
или false
null
). Дополнительные сведения см. в разделе "Типы значений, допускающих значение NULL". Начнем с изучения способа использования шаблонов.
Сопоставление значения
Во всех примерах в этом руководстве используются текстовые входные данные, представляющие ряд банковских транзакций в виде входных данных, разделенных запятыми (CSV). В каждом из примеров можно сопоставить запись с шаблоном, используя либо выражение is
, либо выражение switch
. Этот первый пример разбивает каждую строку на ,
символ, а затем сопоставляет первое строковое поле со значением "ДЕПОЗИТ" или "ВЫВОД" с помощью is
выражения. При совпадении сумма транзакции добавляется или вычитается из текущего баланса счета. Чтобы посмотреть, как это работает, нажмите кнопку "Выполнить":
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}");
}
}
Проверьте выходные данные. Вы можете увидеть, что каждая строка обрабатывается, сравнивая значение текста в первом поле. Предыдущий пример можно создать аналогично с помощью ==
оператора, чтобы проверить, равны ли два string
значения. Сравнение переменной с константой является основным стандартным блоком для сопоставления шаблонов. Давайте рассмотрим больше основных элементов, которые являются частью сопоставления шаблонов.
Совпадения элементов перечисления
Частое применение сопоставления шаблонов — это сопоставление значений типа enum
. Следующий пример обрабатывает входные записи, чтобы создать кортеж, где первое значение представляет собой enum
значение, обозначающее депозит или снятие средств. Второе значение — это значение транзакции. Чтобы посмотреть, как это работает, нажмите кнопку "Выполнить":
Предупреждение
Не копируйте и не вставьте. Интерактивное окно должно быть перезагружено для выполнения приведенных ниже примеров. Если вы делаете ошибку, окно зависает, и вам нужно обновить страницу, чтобы продолжить.
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
}
В предыдущем примере также используется if
инструкция для проверки значения enum
выражения. Другая форма сопоставления шаблонов использует switch
выражение. Давайте рассмотрим этот синтаксис и как его можно использовать.
Исчерпывающие совпадения с switch
Ряд if
инструкций может протестировать ряд условий. Но компилятор не может определить, являются ли ряд операторов if
исчерпывающими, или если более поздние if
условия охвачены предыдущими условиями. Выражение switch
гарантирует выполнение обоих этих характеристик, что приводит к меньшим ошибкам в приложениях. Давайте попробуем и поэкспериментируем. Скопируйте следующий код. Замените два if
инструкции в интерактивном окне на выражение switch
, которое вы скопировали. После изменения кода нажмите кнопку "Выполнить" в верхней части интерактивного окна, чтобы запустить новый пример.
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
(TransactionType.Withdrawal, var amount) => -amount,
_ => 0.0,
};
При запуске кода вы увидите, что он работает так же. Чтобы продемонстрировать подсумпцию, переставьте ветви переключателя, как показано в следующем фрагменте:
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
_ => 0.0,
(TransactionType.Withdrawal, var amount) => -amount,
};
После переупорядочения переупорядочения оружия нажмите кнопку "Выполнить". Компилятор выдает ошибку, потому что ветвь с _
совпадает с каждым возможным значением. В результате, этот последний сегмент с TransactionType.Withdrawal
никогда не выполняется. Компилятор сообщает, что в коде что-то не так.
Компилятор выдает предупреждение, если выражение, проверенное в switch
выражении, может содержать значения, которые не соответствуют ни одной ветви switch. Если некоторые значения не могут соответствовать любому условию, switch
выражение не является исчерпывающим. Компилятор также выдает предупреждение, если некоторые значения входных данных не соответствуют ни одной из ветвей оператора switch. Например, при удалении строки с _ => 0.0,
недопустимыми значениями не совпадают. Во время выполнения произойдёт ошибка. После установки пакета SDK для .NET и сборки программ в среде можно проверить это поведение. Веб-интерфейс не отображает предупреждения в окне вывода.
Шаблоны типов
Чтобы завершить работу с этим руководством, давайте рассмотрим еще один ключевой элемент для сопоставления шаблонов: типовой шаблон.
Шаблон типа проверяет выражение во время выполнения, чтобы узнать, является ли он указанным типом. С выражением is
или switch
выражением можно использовать тест типа. Давайте изменим текущий пример двумя способами. Во-первых, вместо кортежа давайте создадим Deposit
и Withdrawal
типы записей, которые представляют транзакции. Добавьте следующие объявления в нижней части интерактивного окна:
public record Deposit(double Amount, string description);
public record Withdrawal(double Amount, string description);
Затем добавьте этот метод после Main
метода для анализа текста и возврата ряда записей:
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;
}
}
Наконец, замените foreach
цикл в Main
методе следующим кодом:
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}");
}
Затем нажмите кнопку "Выполнить", чтобы просмотреть результаты. Эта окончательная версия проверяет входные данные по типу.
Сопоставление шаблонов предоставляет словарь для сравнения выражения с характеристиками. Шаблоны могут включать тип выражения, значения типов, значений свойств и сочетаний этих выражений. Сравнение выражений с шаблоном может быть более четким, чем несколько if
сравнений. Вы изучили некоторые шаблоны, которые можно использовать для сопоставления выражений. Существует множество способов использования сопоставления шаблонов в приложениях. Сначала посетите сайт .NET, чтобы скачать пакет SDK для .NET , создать проект на компьютере и сохранить код. При изучении вы можете узнать больше о сопоставлении шаблонов в C# в следующих статьях: