C# -

Extended Property Patterns

Extended property patterns in C# were introduced in C# 10.0. They provide a more concise and readable way to match properties within nested objects. This tutorial will cover the basics of extended property patterns, their usage, best practices, and more.


1. Introduction to Extended Property Patterns

Extended property patterns allow you to match nested properties directly within the pattern, making the code more concise and readable. They are particularly useful when working with complex data structures.


2. Basic Usage

Here's a basic example of an extended property pattern:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "John",
            Address = new Address { City = "New York", Country = "USA" }
        };

        if (person is { Address.City: "New York" })
        {
            Console.WriteLine("Person lives in New York.");
        }
    }
}
        
    

3. Matching Nested Properties

Extended property patterns make it easy to match nested properties. Here's an example:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "John",
            Address = new Address { City = "New York", Country = "USA" }
        };

        if (person is { Address: { City: "New York", Country: "USA" } })
        {
            Console.WriteLine("Person lives in New York, USA.");
        }
    }
}
        
    

4. Combining with Other Patterns

You can combine extended property patterns with other pattern matching techniques. Here's an example:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "John",
            Address = new Address { City = "New York", Country = "USA" }
        };

        if (person is { Address: { City: "New York" }, Name: "John" })
        {
            Console.WriteLine("John lives in New York.");
        }
    }
}
        
    

5. Using Extended Property Patterns with Switch Expressions

Extended property patterns can be used within switch expressions for more expressive code. Here's how:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "John",
            Address = new Address { City = "New York", Country = "USA" }
        };

        string location = person switch
        {
            { Address: { City: "New York", Country: "USA" } } => "New Yorker",
            { Address: { Country: "USA" } } => "American",
            _ => "Unknown"
        };

        Console.WriteLine(location);
    }
}
        
    

6. Complex Matching Scenarios

Extended property patterns can handle complex matching scenarios. Here's an example:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "John",
            Address = new Address { City = "New York", Country = "USA" },
            Age = 30
        };

        if (person is { Address: { City: "New York" }, Age: > 25 })
        {
            Console.WriteLine("John lives in New York and is older than 25.");
        }
    }
}
        
    

7. Performance Considerations

While extended property patterns improve code readability, it's important to consider performance implications. Here are some points to keep in mind:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "John",
            Address = new Address { City = "New York", Country = "USA" }
        };

        // Consider the performance implications when using complex patterns
        if (person is { Address: { City: "New York" } })
        {
            Console.WriteLine("Person lives in New York.");
        }
    }
}
        
    

8. Error Handling

Proper error handling is crucial when using extended property patterns. Here's an example:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Person person = null;

        try
        {
            if (person is { Address.City: "New York" })
            {
                Console.WriteLine("Person lives in New York.");
            }
        }
        catch (NullReferenceException)
        {
            Console.WriteLine("Person or Address is null.");
        }
    }
}
        
    

9. Best Practices for Using Extended Property Patterns

Here are some best practices to follow when using extended property patterns in C#:


10. Advanced Examples

Let's look at some advanced examples of using extended property patterns in C#.

Matching Deeply Nested Properties:
        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
    public Company Employer { get; set; }
}

public class Company
{
    public string Name { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "John",
            Address = new Address { City = "New York", Country = "USA" },
            Employer = new Company { Name = "TechCorp" }
        };

        if (person is { Address.City: "New York", Employer.Name: "TechCorp" })
        {
            Console.WriteLine("John works at TechCorp and lives in New York.");
        }
    }
}
        
    
Combining with Logical Patterns:
        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "Jane",
            Address = new Address { City = "Los Angeles", Country = "USA" },
            Age = 28
        };

        if (person is { Address: { City: "Los Angeles" } } and { Age: > 25 })
        {
            Console.WriteLine("Jane lives in Los Angeles and is older than 25.");
        }
    }
        
    

11. Practical Use Cases

Extended property patterns can be used in various practical scenarios. Here are some examples:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
    public DateTime BirthDate { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "Sam",
            Address = new Address { City = "Chicago", Country = "USA" },
            BirthDate = new DateTime(1990, 5, 21)
        };

        if (person is { Address.City: "Chicago", BirthDate.Year: 1990 })
        {
            Console.WriteLine("Sam was born in 1990 and lives in Chicago.");
        }
    }
}
        
    

12. Future Enhancements

As C# evolves, extended property patterns may see further enhancements. Here's what to look forward to:

        
            using System;

namespace ExtendedPropertyPatternsExamples;

public class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "Anna",
            Address = new Address { City = "San Francisco", Country = "USA" },
            Age = 32
        };

        // Example of potential future enhancements (hypothetical)
        if (person is { Address.City: "San Francisco", Age: > 30 })
        {
            Console.WriteLine("Anna lives in San Francisco and is older than 30.");
        }
    }
}
        
    


13. Conclusion

Extended property patterns in C# provide a powerful tool for matching nested properties concisely and readably. By following best practices and understanding their capabilities, you can effectively use extended property patterns to improve your code.