Checkpoint: Types & Data
You've learned nullable types, pattern matching, records, structs, tuples, extension methods, DateTime and regex — let's combine them. This checkpoint isn't new material; it's a chance to prove to yourself that these pieces click together into the kind of small, clean module you'd write in a real C# project.
Learn Checkpoint: Types & Data in our free C# course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free C# course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Notice the through-line: this whole track has been about modelling and handling data . Records and structs give data a shape; nullable operators handle missing data; tuples carry small groupings; pattern matching branches on data's shape; extension methods add fluent helpers; and DateTime and regex tame two of the messiest real-world data types — time and text. Master these together and you can model almost any domain cleanly.
Warm-Up
Run this first to shake off the rust. In a handful of lines it uses the ?? operator and a switch expression together — both should feel familiar now.
🛠️ Build Challenge: an Order Module
Here's the main event — a multi-step build that ties the track together: a record for orders, an extension method that uses a switch expression with property patterns to compute shipping, a with update, and a LINQ revenue total. Fill in the three ___ blanks and run it. Try it yourself before peeking at the solution below.
Attempted it? Compare your version against a clean reference. Yours may differ slightly and still be correct — what matters is the same output.
⏱ Timed Quiz
Answer each before expanding. No peeking — these are exactly the things worth remembering.
1. What does x ?? y evaluate to when x is not null?
x . The right-hand side y is only used when x is null.
2. In a switch expression, what does the _ arm represent, and where should it go?
The discard/default — "match anything else". It should be the last arm so it catches everything not handled above and makes the expression exhaustive.
3. Two records have identical property values. Does a == b return True or False?
True — records use value equality, comparing every property. (A normal class would return False via reference equality.)
4. You assign one struct variable to another and change the copy. Does the original change? What about with a class?
For a struct , the original is unchanged (value types are copied). For a class , the original does change, because both variables reference the same object.
5. What makes a static method an extension method, and what's "hi".Shout() shorthand for?
The this modifier on its first parameter. "hi".Shout() is shorthand for StringExtensions.Shout("hi") .
6. Why use @"\d+" instead of "\d+" for a regex, and what does ^\d+$ require?
A verbatim string @"..." keeps backslashes literal so the pattern is readable. ^\d+$ requires the whole string to be one or more digits (anchors at start and end).
Practice quiz
What does the expression x ?? y evaluate to when x is NOT null?
- y
- null
- x
- false
Answer: x. The null-coalescing operator returns x when x is non-null; y is only used when x is null.
In a switch expression, what does the _ arm represent and where should it go?
- The discard/default 'match anything else'; it goes last
- The first case; it goes at the top
- A null check; placement is irrelevant
- An error case that throws
Answer: The discard/default 'match anything else'; it goes last. _ is the catch-all arm and must be last so the switch expression is exhaustive.
Two records have identical property values. Does a == b return true or false?
- false — reference equality
- It throws an exception
- Only if they are the same reference
- true — records use value equality
Answer: true — records use value equality. Records compare by value across all properties, so equal contents give true (unlike a normal class).
You assign one struct variable to another and change the copy. Does the original change?
- Yes, structs are shared by reference
- No, structs are value types and are copied
- Only if the struct has properties
- Structs cannot be copied
Answer: No, structs are value types and are copied. Structs are value types: assignment makes an independent copy, so the original is untouched.
What makes a static method an extension method?
- The 'this' modifier on its first parameter
- The static keyword on the class
- Returning the same type it extends
- Being placed in a namespace
Answer: The 'this' modifier on its first parameter. An extension method's first parameter is marked with 'this', letting you call it like an instance method.
What does the 'with' expression do on a record, as in order with { Status = "paid" }?
- Mutates the record in place
- Deletes the named property
- Creates a new record copy with the listed properties changed
- Compares two records
Answer: Creates a new record copy with the listed properties changed. 'with' performs a non-destructive copy, producing a new record that differs only in the named members.
Why use a verbatim string @"\d+" instead of "\d+" for a regex pattern?
- It runs faster
- It keeps backslashes literal so the pattern stays readable
- It is required by Regex.Match
- It makes the regex case-insensitive
Answer: It keeps backslashes literal so the pattern stays readable. A verbatim @ string does not process escape sequences, so regex backslashes are written once and read clearly.
What does the regex ^\d+$ require of a string?
- It contains at least one digit somewhere
- It starts with a digit
- It ends with a digit
- The whole string is one or more digits
Answer: The whole string is one or more digits. The ^ and $ anchors require the entire string to consist of one or more digits.
What is a tuple useful for in C#?
- Replacing all classes
- Carrying a small, lightweight grouping of values, often via deconstruction
- Storing key/value lookups
- Pattern matching only
Answer: Carrying a small, lightweight grouping of values, often via deconstruction. Tuples bundle a few related values together cheaply and can be deconstructed into separate variables.
Which LINQ call sums the Total of orders whose Status is "paid"?
- orders.Sum(x => x.Total)
- orders.Count(x => x.Status == "paid")
- orders.Where(x => x.Status == "paid").Sum(x => x.Total)
- orders.Select(x => x.Total).First()
Answer: orders.Where(x => x.Status == "paid").Sum(x => x.Total). Where filters to paid orders first, then Sum adds up their Total values.