Skip to content

Commit 2543795

Browse files
committed
First pass at the code.
1 parent 9bd2fc4 commit 2543795

File tree

4 files changed

+277
-1
lines changed

4 files changed

+277
-1
lines changed

docs/csharp/tour-of-csharp/tutorials/index.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Interactive tutorials
33
description: Learn C# in your browser, and get started with your own development environment
4-
ms.date: 03/20/2025
4+
ms.date: 04/23/2025
55
---
66
# Introduction to C\#
77

@@ -37,6 +37,14 @@ The [Branches and loops](branches-and-loops.md) tutorial teaches the basics of s
3737

3838
The [List collection](list-collection.md) lesson gives you a tour of the List collection type that stores sequences of data. You'll learn how to add and remove items, search for items, and sort the lists. You'll explore different kinds of lists.
3939

40+
## Tuples and types
41+
42+
The [Tuples and types](tuples-and-types.md) lesson provides an overview of how you can create types in C#. The lesson focuses on tuples and records. It introduces the concepts of classes and structures, which are used more often in larger projects. You'll learn much more about these types after you install the .NET SDK and build more and larger apps.
43+
44+
## Pattern matching
45+
46+
The [Pattern matching](pattern-matching.md) lesson provides an introduction to *pattern matching*. Pattern matching enables you to compare an expression against a pattern. The success of the match determines which program logic to follow. Patterns can compare types, properties of a type, or contents of a list. You can combine multiple patterns using `and`, `or`, and `not` logic. Patterns provide a rich vocabulary to inspect data and make decisions in your program based on that inspection.
47+
4048
## Set up your local environment
4149

4250
After you finish these tutorials, set up a development environment. You'll want:
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: Pattern matching
3+
description: In this tutorial about creating types, you use your browser to learn C# interactively. You're going to write C# code and see the results of compiling and running your code directly in the browser.
4+
ms.date: 04/28/2025
5+
---
6+
# Matching data against patterns
7+
8+
This tutorial teaches you how to use pattern matching to inspect data in C#. You write small amounts of code, then you compile and run that code. The tutorial contains a series of lessons that explore different kinds of types in C#. These lessons teach you the fundamentals of the C# language.
9+
10+
> [!TIP]
11+
> When a code snippet block includes the "Run" button, that button opens the interactive window, or replaces the existing code in the interactive window. When the snippet doesn't include a "Run" button, you can copy the code and add it to the current interactive window.
12+
13+
The preceding tutorials demonstrated built in types and types you define as tuples or records. Instances of these types can be checked against a *pattern*. Whether an instance matches a pattern determines the actions your program takes. Let's start to explore how you can use patterns.
14+
15+
All the examples in this tutorial use the following data. Select "Run" to start the interactive window and copy this data into the window:
16+
17+
:::code language="csharp" interactive="try-dotnet-method" source="./snippets/PatternMatching/Program.cs" id="InputData":::
18+
19+
## Match a value with `is`
20+
21+
:::code language="csharp" interactive="try-dotnet-method" source="./snippets/PatternMatching/Program.cs" id="IsOnTextValue":::
22+
23+
:::code language="csharp" interactive="try-dotnet-method" source="./snippets/PatternMatching/Program.cs" id="IsEnumValue":::
24+
25+
## Exhaustive matches with `switch`
26+
27+
:::code language="csharp" interactive="try-dotnet-method" source="./snippets/PatternMatching/Program.cs" id="SwitchEnumValue":::
28+
29+
## Match on types
30+
31+
> [!WARNING]
32+
> Don't copy and paste. The interactive window must be reset to run the following sample. If you make a mistake, the window hangs, and you need to refresh the page to continue.
33+
34+
The following code declares and uses a `record` type to represent a `Point`, and then uses that `Point` structure in the `Main` method:
35+
36+
:::code language="csharp" interactive="try-dotnet" source="./snippets/PatternMatching/Program.cs" id="FinalProgram":::
37+
38+
You completed the "Introduction to pattern matching C#" interactive tutorial. You can visit the [.NET site](https://dotnet.microsoft.com/learn/dotnet/hello-world-tutorial/intro) to download the .NET SDK, create a project on your machine, and keep coding.
39+
40+
You can learn more about pattern matching in C# in the following articles:
41+
42+
- [Pattern matching in C#](../../fundamentals/functional/pattern-matching.md)
43+
- [Explore pattern matching tutorial](../../tutorials/patterns-objects.md)
44+
- [Pattern matching scenario](../../fundamentals/tutorials/pattern-matching.md)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
</Project>
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
// <InputData>
2+
string bankRecords = """
3+
DEPOSIT, 10000, Initial balance
4+
DEPOSIT, 500, regular deposit
5+
WITHDRAWAL, 1000, rent
6+
DEPOSIT, 2000, freelance payment
7+
WITHDRAWAL, 300, groceries
8+
DEPOSIT, 700, gift from friend
9+
WITHDRAWAL, 150, utility bill
10+
DEPOSIT, 1200, tax refund
11+
WITHDRAWAL, 500, car maintenance
12+
DEPOSIT, 400, cashback reward
13+
WITHDRAWAL, 250, dining out
14+
DEPOSIT, 3000, bonus payment
15+
WITHDRAWAL, 800, loan repayment
16+
DEPOSIT, 600, stock dividends
17+
WITHDRAWAL, 100, subscription fee
18+
DEPOSIT, 1500, side hustle income
19+
WITHDRAWAL, 200, fuel expenses
20+
DEPOSIT, 900, refund from store
21+
WITHDRAWAL, 350, shopping
22+
DEPOSIT, 2500, project milestone payment
23+
WITHDRAWAL, 400, entertainment
24+
""";
25+
// </InputData>
26+
27+
await IsTextValueExample(bankRecords);
28+
Console.WriteLine();
29+
await IsEnumValueExample(bankRecords);
30+
Console.WriteLine();
31+
await SwitchEnumValueExample(bankRecords);
32+
Console.WriteLine();
33+
await ExampleProgram.Main();
34+
Console.WriteLine();
35+
36+
static async Task IsTextValueExample(string inputText1)
37+
{
38+
// <IsOnTextValue>
39+
double currentBalance = 0.0;
40+
var reader = new StringReader(inputText1);
41+
42+
string? line;
43+
while ((line = await reader.ReadLineAsync()) != null)
44+
{
45+
if (string.IsNullOrWhiteSpace(line)) continue;
46+
// Split the line based on comma delimiter and trim each part
47+
string[] parts = line.Split(',');
48+
49+
string? transactionType = parts[0]?.Trim();
50+
if (double.TryParse(parts[1].Trim(), out double amount))
51+
{
52+
// Update the balance based on transaction type
53+
if (transactionType?.ToUpper() is "DEPOSIT")
54+
currentBalance += amount;
55+
else if (transactionType?.ToUpper() is "WITHDRAWAL")
56+
currentBalance -= amount;
57+
58+
Console.WriteLine($"{line.Trim()} => Parsed Amount: {amount}, New Balance: {currentBalance}");
59+
}
60+
}
61+
// </IsOnTextValue>
62+
}
63+
64+
static async Task IsEnumValueExample(string inputText1)
65+
{
66+
// <IsEnumValue>
67+
double currentBalance = 0.0;
68+
69+
await foreach(var transaction in TransactionRecords(inputText1))
70+
{
71+
if (transaction.type == TransactionType.Deposit)
72+
currentBalance += transaction.amount;
73+
else if (transaction.type == TransactionType.Withdrawal)
74+
currentBalance -= transaction.amount;
75+
Console.WriteLine($"{transaction.type} => Parsed Amount: {transaction.amount}, New Balance: {currentBalance}");
76+
}
77+
78+
static async IAsyncEnumerable<(TransactionType type, double amount)> TransactionRecords(string inputText)
79+
{
80+
var reader = new StringReader(inputText);
81+
string? line;
82+
while ((line = await reader.ReadLineAsync()) != null)
83+
{
84+
string[] parts = line.Split(',');
85+
86+
string? transactionType = parts[0]?.Trim();
87+
if (double.TryParse(parts[1].Trim(), out double amount))
88+
{
89+
// Update the balance based on transaction type
90+
if (transactionType?.ToUpper() is "DEPOSIT")
91+
yield return (TransactionType.Deposit, amount);
92+
else if (transactionType?.ToUpper() is "WITHDRAWAL")
93+
yield return (TransactionType.Withdrawal, amount);
94+
}
95+
yield return (default, 0.0);
96+
}
97+
}
98+
// </IsEnumValue>
99+
}
100+
101+
static async Task SwitchEnumValueExample(string inputText1)
102+
{
103+
// <SwitchEnumValue>
104+
double currentBalance = 0.0;
105+
106+
await foreach (var transaction in TransactionRecords(inputText1))
107+
{
108+
currentBalance += transaction switch
109+
{ (TransactionType.Deposit, var amount) => amount,
110+
(TransactionType.Withdrawal, var amount) => -amount,
111+
_ => 0.0
112+
};
113+
Console.WriteLine($"{transaction.type} => Parsed Amount: {transaction.amount}, New Balance: {currentBalance}");
114+
}
115+
116+
static async IAsyncEnumerable<(TransactionType type, double amount)> TransactionRecords(string inputText)
117+
{
118+
var reader = new StringReader(inputText);
119+
string? line;
120+
while ((line = await reader.ReadLineAsync()) != null)
121+
{
122+
string[] parts = line.Split(',');
123+
124+
string? transactionType = parts[0]?.Trim();
125+
if (double.TryParse(parts[1].Trim(), out double amount))
126+
{
127+
// Update the balance based on transaction type
128+
if (transactionType?.ToUpper() is "DEPOSIT")
129+
yield return (TransactionType.Deposit, amount);
130+
else if (transactionType?.ToUpper() is "WITHDRAWAL")
131+
yield return (TransactionType.Withdrawal, amount);
132+
}
133+
yield return (default, 0.0);
134+
}
135+
}
136+
// </SwitchEnumValue>
137+
}
138+
139+
// <FinalProgram>
140+
public static class ExampleProgram
141+
{
142+
static string bankRecords = """
143+
DEPOSIT, 10000, Initial balance
144+
DEPOSIT, 500, regular deposit
145+
WITHDRAWAL, 1000, rent
146+
DEPOSIT, 2000, freelance payment
147+
WITHDRAWAL, 300, groceries
148+
DEPOSIT, 700, gift from friend
149+
WITHDRAWAL, 150, utility bill
150+
DEPOSIT, 1200, tax refund
151+
WITHDRAWAL, 500, car maintenance
152+
DEPOSIT, 400, cashback reward
153+
WITHDRAWAL, 250, dining out
154+
DEPOSIT, 3000, bonus payment
155+
WITHDRAWAL, 800, loan repayment
156+
DEPOSIT, 600, stock dividends
157+
WITHDRAWAL, 100, subscription fee
158+
DEPOSIT, 1500, side hustle income
159+
WITHDRAWAL, 200, fuel expenses
160+
DEPOSIT, 900, refund from store
161+
WITHDRAWAL, 350, shopping
162+
DEPOSIT, 2500, project milestone payment
163+
WITHDRAWAL, 400, entertainment
164+
""";
165+
166+
public static async Task Main()
167+
{
168+
double currentBalance = 0.0;
169+
170+
await foreach (var transaction in TransactionRecordType(bankRecords))
171+
{
172+
currentBalance += transaction switch
173+
{
174+
Deposit d => d.Amount,
175+
Withdrawal w => -w.Amount,
176+
_ => 0.0
177+
};
178+
Console.WriteLine($" {transaction} => New Balance: {currentBalance}");
179+
}
180+
}
181+
182+
public static async IAsyncEnumerable<object?> TransactionRecordType(string inputText)
183+
{
184+
var reader = new StringReader(inputText);
185+
string? line;
186+
while ((line = await reader.ReadLineAsync()) != null)
187+
{
188+
string[] parts = line.Split(',');
189+
190+
string? transactionType = parts[0]?.Trim();
191+
if (double.TryParse(parts[1].Trim(), out double amount))
192+
{
193+
// Update the balance based on transaction type
194+
if (transactionType?.ToUpper() is "DEPOSIT")
195+
yield return new Deposit(amount, parts[2]);
196+
else if (transactionType?.ToUpper() is "WITHDRAWAL")
197+
yield return new Withdrawal(amount, parts[2]);
198+
}
199+
yield return default;
200+
}
201+
}
202+
}
203+
204+
public enum TransactionType
205+
{
206+
Deposit,
207+
Withdrawal
208+
}
209+
210+
211+
public record Deposit(double Amount, string description);
212+
public record Withdrawal(double Amount, string description);
213+
214+
// </FinalProgram>

0 commit comments

Comments
 (0)