Kurz: Použití jazyka C# ke porovnávání dat se vzory

V tomto kurzu se naučíte používat porovnávání vzorů ke kontrole dat v jazyce C#. Napíšete malé množství kódu, pak tento kód zkompilujete a spustíte. Tento kurz obsahuje řadu lekcí, které prozkoumávají různé druhy vzorů podporovaných jazykem C#. Tyto lekce vás naučí základy jazyka C#.

Návod

Začínáte s programováním? Projděte si jednotlivé oddíly v pořadí. Pochází z jiného jazyka? Pokud již znáte switch příkazy, zaměřte se na úplné shody a typové vzory – jedná se o charakteristické prvky jazyka C#.

V tomto kurzu se naučíte:

  • Spusťte GitHub Codespace s vývojovým prostředím jazyka C#.
  • Otestujte data pro diskrétní hodnoty.
  • Porovná data výčtu s hodnotou.
  • Vytvářejte úplné shody pomocí switch výrazů.
  • Porovnává typy pomocí vzorů typů.

Požadavky

Musíte mít jednu z následujících možností:

Přiřadit hodnotu

Předchozí kurzy demonstrovaly předdefinované typy a typy, které definujete jako řazené kolekce členů nebo záznamy. Instance těchto typů můžete zkontrolovat proti vzoru. Jestli instance odpovídá vzoru, určuje akce, které váš program provede. V následujících příkladech uvidíte ? po názvech typů. Tento symbol umožňuje, aby hodnota tohoto typu byla null (například bool? může být true, falsenebo null). Další informace naleznete v tématu nulovatelné typy hodnot. Pojďme se podívat, jak můžete používat vzory.

Pokud chcete spustit GitHub Codespace s výukovým prostředím, otevřete okno prohlížeče na úložišti výukového codespace. Vyberte zelené tlačítko Kód a kartu Codespaces . Pak výběrem znaménka + vytvořte nový Codespace pomocí tohoto prostředí. Pokud jste dokončili další kurzy v této sérii, můžete tento prostor kódu otevřít.

  1. Když se váš codespace načte, vytvořte nový soubor ve složce kurzů s názvem patterns.cs.

  2. Otevřete nový soubor.

  3. Všechny příklady v tomto kurzu používají textový vstup, který představuje řadu bankovních transakcí jako vstup hodnot oddělených čárkami (CSV). V každé ukázce můžete záznam spárovat se vzorem buď pomocí výrazu is, nebo výrazu switch. Tento první příklad rozdělí každý řádek podle znaku , a poté porovná první pole typu string s hodnotou "DEPOSIT" nebo "WITHDRAWAL" pomocí výrazu . Když se shoduje, částka transakce se přidá nebo odečte od aktuálního zůstatku účtu. Pokud chcete vidět, jak funguje, přidejte do patterns.cs následující kód:

    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}");
        }
    }
    
  4. Potom do okna terminálu zadejte následující text:

    cd tutorials
    dotnet patterns.cs
    
  5. Prozkoumejte výstup. Můžete vidět, že každý řádek je zpracován porovnáním hodnoty textu v prvním poli.

Podobným způsobem byste mohli vytvořit předchozí vzorek pomocí operátoru == k otestování, že jsou dvě string hodnoty stejné. Porovnání proměnné s konstantou je základním stavebním blokem pro porovnávání vzorů. Pojďme se podívat na další stavební bloky, které jsou součástí porovnávání vzorů.

Návod

Víc se uč: Přečtěte si o porovnávání vzorů v části Základy jazyka C#, kde najdete úplný přehled všech typů vzorů.

Shody výčtového typu

Dalším běžným použitím porovnávání vzorů je porovnávání hodnot enum typu. Následující ukázka zpracuje vstupní záznamy a vytvoří n-tici, kde první hodnota je enum hodnota zaznamenávající vklad nebo výběr. Druhá hodnota je hodnota transakce.

  1. Na konec zdrojového souboru přidejte následující kód. Definuje výčet TransactionType :

    public enum TransactionType
    {
        Deposit,
        Withdrawal,
        Invalid
    }
    
  2. Přidejte funkci pro parsování bankovní transakce do dvojice, která obsahuje typ transakce a hodnotu transakce. Před deklaraci výčtu TransactionType přidejte následující kód:

    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);
            }
        }
    }
    
  3. Přidejte novou smyčku pro zpracování transakčních dat pomocí výčtu TransactionType , který jste deklarovali:

    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}");
    }
    

Předchozí příklad také používá příkaz if ke kontrole hodnoty výrazu enum . Jiná forma porovnávání vzorů používá výraz switch. Pojďme se na tuto syntaxi podívat a jak ji můžete použít.

Vyčerpávající shody s switch

if Řada příkazů může testovat řadu podmínek. Kompilátor ale nemůže zjistit, jestli je řada if příkazů úplná nebo jestli jsou pozdější if podmínky přehlíženy dřívějšími podmínkami. Vyčerpávající znamená, že jedna z ifelse klauzulí v řadě testů zpracovává všechny možné vstupy. Pokud je řada if příkazů vyčerpávající, všechny možné vstupy splňují alespoň jednu if nebo else klauzuli. Subsumption znamená, že nelze dosáhnout pozdější if nebo else klauzule, protože dřívější if nebo else klauzule odpovídají všem možným vstupům. Například v následujícím příkladu kódu jedna klauzule nikdy neodpovídá:

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");

Klauzule else if nikdy neodpovídá, protože každé číslo menší než 10 je také menší než 20. Výraz switch zajistí splnění obou těchto vlastností, což vede k menšímu počtu chyb ve vašich aplikacích. Pojďme to vyzkoušet a experimentovat.

  1. Zkopírujte následující kód. Nahraďte dva if příkazy ve smyčce foreach výrazem switch , který jste zkopírovali.

    currentBalance += transaction switch
    {
        (TransactionType.Deposit, var amount) => amount,
        (TransactionType.Withdrawal, var amount) => -amount,
        _ => 0.0,
    };
    
  2. Zadáním dotnet patterns.cs do okna terminálu spusťte novou ukázku.

    Když kód spustíte, uvidíte, že funguje stejně.

  3. Pokud chcete předvést subsumption, změňte pořadí ramen přepínače, jak je znázorněno v následujícím fragmentu kódu:

    currentBalance += transaction switch
    {
        (TransactionType.Deposit, var amount) => amount,
        _ => 0.0,
        (TransactionType.Withdrawal, var amount) => -amount,
    };
    

    Po přeuspořádání ramen přepínače zadejte dotnet patterns.cs do okna terminálu. Kompilátor hlásí chybu, protože větev se shoduje s _ každou hodnotou. Výsledkem je, že konečná větev s TransactionType.Withdrawal nikdy neprobíhá. Kompilátor vám řekne, že v kódu něco není v pořádku.

    Kompilátor hlásí upozornění, pokud výraz testovaný ve výrazu switch může obsahovat hodnoty, které neodpovídají žádné větvi přepínače. Pokud některé hodnoty neodpovídají žádné podmínce, switch výraz není vyčerpávající. Kompilátor také hlásí upozornění, pokud některé hodnoty vstupu neodpovídají žádné z přepínacích ramen.

  4. Odeberte řádek s _ => 0.0,, aby se žádné neplatné hodnoty neshodovaly.

  5. Zadáním dotnet patterns.cs zobrazíte výsledky.

    Kompilátor hlásí upozornění. Testovací data jsou platná, takže program funguje. Avšak, jakákoli neplatná data by způsobila chybu během běhu programu.

Vzory typů

Pokud chcete tento kurz dokončit, prozkoumejte jeden další stavební blok pro porovnávání vzorů: vzor typu. Vzor typu testuje výraz za běhu, aby zjistil, jestli se jedná o zadaný typ. Test typu můžete použít buď s výrazem is , nebo výrazem switch . Upravte aktuální ukázku dvěma způsoby. Nejprve místo tuplu sestavte záznamové typy Deposit a Withdrawal, které reprezentují transakce.

  1. Na konec souboru kódu přidejte následující deklarace:

    public record Deposit(double Amount, string description);
    public record Withdrawal(double Amount, string description);
    
  2. Tuto metodu přidejte těsně před deklaraci výčtu TransactionType . Analyzuje text a vrátí řadu záznamů:

    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]);
            }
        }
    }
    
  3. Za poslední foreach smyčku přidejte následující kód:

    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}");
    }
    
  4. Pokud chcete zobrazit výsledky, zadejte dotnet patterns.cs okno terminálu. Tato konečná verze testuje vstup proti typu.

Porovnávání vzorů poskytuje slovní zásobu pro porovnání výrazu s charakteristikami. Vzory můžou zahrnovat typ výrazu, hodnoty typů, hodnot vlastností a jejich kombinace. Porovnávání výrazů podle vzoru může být srozumitelnější než více if porovnání. Prozkoumali jste některé vzory, které můžete použít k porovnávání výrazů. Existuje mnoho dalších způsobů, jak ve svých aplikacích použít porovnávání vzorů. Při zkoumání se můžete dozvědět více o porovnávání vzorů v jazyce C# v následujících článcích:

Úklid zdrojů

GitHub automaticky odstraní váš Codespace po 30 dnech nečinnosti. Dokončili jste všechny kurzy v této sérii. Pokud chcete nyní odstranit Codespace, otevřete okno prohlížeče a přejděte do codespaces. V okně by se měl zobrazit seznam Codespaces. Vyberte tři tečky (...) v položce výukového kurzu codespace a vyberte odstranit.

Další kroky

Dokončili jste všechny úvodní kurzy! Tady je postup: