0
0
C Sharp (C#)programming~15 mins

Property patterns in C Sharp (C#) - Deep Dive

Choose your learning style9 modes available
Overview - Property patterns
What is it?
Property patterns in C# let you check if an object has certain properties with specific values or shapes. Instead of writing many if statements, you can write a clear pattern that matches the object's properties. This makes your code easier to read and understand. It works by comparing the properties of an object directly inside a pattern expression.
Why it matters
Without property patterns, checking an object's properties means writing long, nested if statements that are hard to read and maintain. Property patterns simplify this by letting you write concise, clear checks. This reduces bugs and makes your code cleaner, especially when working with complex objects or data structures.
Where it fits
Before learning property patterns, you should know basic C# syntax, how to use if statements, and understand classes and properties. After mastering property patterns, you can explore more advanced pattern matching features like positional patterns, relational patterns, and switch expressions.
Mental Model
Core Idea
Property patterns let you match an object by directly checking its properties in a clear, concise way.
Think of it like...
It's like checking the labels on a box to see if it contains the items you want, instead of opening the box and inspecting each item one by one.
Object
  │
  ├─ Property1: value1
  ├─ Property2: value2
  └─ Property3: value3

Pattern: { Property1: expected1, Property2: expected2 }

Match if Object.Property1 == expected1 AND Object.Property2 == expected2
Build-Up - 7 Steps
1
FoundationUnderstanding basic property access
🤔
Concept: Learn how to read properties from an object in C#.
In C#, objects have properties that hold data. For example: class Person { public string Name { get; set; } public int Age { get; set; } } You can access these properties like this: Person p = new Person { Name = "Alice", Age = 30 }; string name = p.Name; // "Alice" int age = p.Age; // 30
Result
You can get the values stored in an object's properties.
Understanding how to access properties is essential because property patterns work by checking these values directly.
2
FoundationIntroduction to pattern matching basics
🤔
Concept: Learn the simplest form of pattern matching using the 'is' keyword.
C# lets you check if an object is a certain type using pattern matching: if (obj is Person p) { // p is now a Person } This checks the type and casts in one step.
Result
You can test an object's type and use it safely inside the if block.
Pattern matching starts with type checks, which property patterns build upon by adding property value checks.
3
IntermediateUsing property patterns for simple checks
🤔
Concept: Learn how to check an object's properties directly in a pattern.
You can write: if (obj is Person { Name: "Alice" }) { // Matches if obj is Person and Name is "Alice" } This replaces: if (obj is Person p && p.Name == "Alice") { // ... }
Result
The code is shorter and clearer when checking properties.
Property patterns let you combine type and property checks in one expression, improving readability.
4
IntermediateCombining multiple property checks
🤔Before reading on: do you think you can check two properties at once with property patterns? Commit to your answer.
Concept: You can check several properties together inside one pattern.
Example: if (obj is Person { Name: "Alice", Age: 30 }) { // Matches if Name is "Alice" AND Age is 30 } This is like writing: if (obj is Person p && p.Name == "Alice" && p.Age == 30) { // ... }
Result
You can match objects with multiple property conditions cleanly.
Knowing you can check many properties at once helps write concise and expressive conditions.
5
IntermediateUsing nested property patterns
🤔Before reading on: do you think property patterns can check properties inside properties? Commit to your answer.
Concept: Property patterns can check nested objects' properties too.
Suppose Person has an Address property: class Address { public string City { get; set; } } class Person { public string Name { get; set; } public Address Address { get; set; } } You can write: if (obj is Person { Address: { City: "Paris" } }) { // Matches if Address.City is "Paris" }
Result
You can match deep inside object graphs easily.
Nested patterns let you express complex conditions without verbose code.
6
AdvancedUsing property patterns with switch expressions
🤔Before reading on: do you think property patterns can be used inside switch expressions? Commit to your answer.
Concept: Property patterns work inside switch expressions for clean branching logic.
Example: string GetPersonInfo(object obj) => obj switch { Person { Name: "Alice" } => "Hello Alice", Person { Age: > 60 } => "Senior person", _ => "Unknown" };
Result
You get clear, readable code that handles many cases based on properties.
Combining property patterns with switch expressions creates powerful, expressive code for decision making.
7
ExpertPerformance and compiler optimizations
🤔Before reading on: do you think property patterns create new objects or slow down your code? Commit to your answer.
Concept: Property patterns are compiled into efficient code without extra object creation.
The compiler translates property patterns into simple property reads and comparisons. It does not create new objects or use reflection. This means property patterns are fast and safe to use in performance-critical code.
Result
You can use property patterns without worrying about performance hits.
Understanding the compiled form prevents misconceptions about runtime costs and encourages confident use in production.
Under the Hood
When you write a property pattern, the C# compiler generates code that first checks the object's type, then reads each specified property, and compares it to the expected value. This is done using direct property accessors, not reflection. Nested property patterns become nested property accesses and comparisons. The compiler optimizes these checks into efficient IL code that runs quickly at runtime.
Why designed this way?
Property patterns were introduced to simplify and unify how developers check object shapes and values. Before, many verbose if statements were needed. The design balances expressiveness and performance by using compile-time transformations instead of runtime reflection. This approach fits well with C#'s static typing and pattern matching evolution, making code safer and clearer.
Object
  │
  ├─ Type check (is Person?)
  │    ↓
  ├─ Property read (Name)
  │    ↓
  ├─ Compare to expected value
  │    ↓
  ├─ Property read (Age)
  │    ↓
  ├─ Compare to expected value
  │    ↓
  └─ Result: match or no match
Myth Busters - 4 Common Misconceptions
Quick: Does a property pattern create a new object or copy the original? Commit to yes or no.
Common Belief:Property patterns create new objects or copies when matching.
Tap to reveal reality
Reality:Property patterns only read existing properties; they do not create or copy objects.
Why it matters:Believing this causes unnecessary fear about performance and memory use, stopping developers from using property patterns.
Quick: Can property patterns check private properties? Commit to yes or no.
Common Belief:Property patterns can match any property, including private ones.
Tap to reveal reality
Reality:Property patterns can only check accessible properties (usually public). Private properties are not accessible for matching.
Why it matters:Expecting private properties to be matched leads to bugs where patterns never match as intended.
Quick: Does a property pattern require all properties to be present? Commit to yes or no.
Common Belief:All properties in a pattern must exist and be non-null to match.
Tap to reveal reality
Reality:If a property is null or missing, the pattern does not match unless you explicitly handle nulls in the pattern.
Why it matters:Not handling nulls causes unexpected mismatches and runtime errors.
Quick: Can property patterns be used with fields instead of properties? Commit to yes or no.
Common Belief:Property patterns work with any member, including fields.
Tap to reveal reality
Reality:Property patterns only work with properties, not fields.
Why it matters:Trying to match fields causes compile errors or unexpected behavior.
Expert Zone
1
Property patterns do not evaluate properties multiple times; the compiler caches values to avoid side effects.
2
When combining property patterns with relational patterns (like > or <), the compiler generates optimized code that avoids redundant checks.
3
Nullable reference types affect property pattern matching; a property marked nullable requires explicit null checks in patterns to avoid mismatches.
When NOT to use
Avoid property patterns when you need to match private or internal state not exposed by properties. In such cases, use methods or explicit if statements. Also, for very complex logic involving side effects or asynchronous checks, property patterns are not suitable.
Production Patterns
In real-world code, property patterns are often used in switch expressions for routing logic, validation checks, and filtering collections. They help write clean domain logic by matching on DTOs or API request objects. Combined with records and init-only properties, they enable immutable data checks with minimal code.
Connections
Structural typing
Property patterns build on the idea of matching an object's shape, similar to structural typing in other languages.
Understanding structural typing helps grasp how property patterns focus on an object's properties rather than its exact type.
JSON schema validation
Both property patterns and JSON schema validation check if data matches expected shapes and values.
Knowing JSON schema helps understand the purpose of property patterns: validating data structure and content simply.
Pattern recognition in cognitive science
Property patterns are a form of pattern recognition, identifying if data fits a known pattern.
Recognizing this connection shows how programming patterns mirror human thinking about categorizing and matching information.
Common Pitfalls
#1Trying to match a field instead of a property.
Wrong approach:if (obj is MyClass { myField: 10 }) { /* ... */ }
Correct approach:if (obj is MyClass { MyProperty: 10 }) { /* ... */ }
Root cause:Confusing fields and properties; property patterns only work with properties.
#2Not handling null nested properties causing exceptions.
Wrong approach:if (obj is Person { Address: { City: "Paris" } }) { /* ... */ } // throws if Address is null
Correct approach:if (obj is Person { Address: { City: "Paris" } } or Person { Address: null }) { /* ... */ }
Root cause:Assuming nested properties are never null without null checks.
#3Using property patterns on types without accessible properties.
Wrong approach:if (obj is SomeType { PrivateProp: 5 }) { /* ... */ }
Correct approach:Use methods or public properties instead, e.g., if (obj is SomeType s && s.GetValue() == 5) { /* ... */ }
Root cause:Expecting property patterns to access private or inaccessible members.
Key Takeaways
Property patterns let you check an object's properties directly and clearly in C#.
They simplify code by combining type and property checks into one expression.
Nested property patterns allow matching deep object structures without verbose code.
Property patterns compile into efficient code without creating new objects or using reflection.
Understanding their limits, like only working with accessible properties, helps avoid common bugs.