Type Patterns & Declaration Patterns (`is` vs `as`)
1Concept
Pattern matching `if (obj is TargetType t)` combines type inspection and variable assignment into a single atomic operation, completely obsoleting unsafe `as` casting followed by null checks.
2Architecture Diagram
Legacy: Object ──> (as Target) ──> Check != null ──> Use target Modern C# Pattern: Object ──> `is Target t` ──> Single IL isinst Opcode + Immediate Scope Assignment
3Code Example
C# 13 & .NET 9
using System;
public abstract record PaymentMethod;
public record CreditCard(string CardNumber, decimal Limit) : PaymentMethod;
public record BankTransfer(string Iban, string Swift) : PaymentMethod;
public class TypePatternDemo
{
public static void ProcessPayment(PaymentMethod payment)
{
if (payment is CreditCard { Limit: > 1000 } cc)
{
Console.WriteLine($"Approved high-limit Credit Card: {cc.CardNumber[^4..]}");
}
else if (payment is BankTransfer bt)
{
Console.WriteLine($"Bank Transfer via IBAN: {bt.Iban}");
}
}
public static void Main()
{
ProcessPayment(new CreditCard("4111222233334444", 5000m));
ProcessPayment(new BankTransfer("DE89370400440532013000", "DEUTDEDB"));
}
}4Expected Output
Approved high-limit Credit Card: 4444 Bank Transfer via IBAN: DE89370400440532013000
5Key Takeaways
- ✓`is` with declaration patterns prevents double casting in IL bytecode.
- ✓Property sub-patterns `{ Limit: > 1000 }` enable recursive deep evaluation.
- ✓Combine with `not` patterns (e.g. `if (input is not null)`) for idiomatic C#.