Why Use C# 11's Extended Property Patterns

Why Use C# 11's Extended Property Patterns

Some extended features scratch an itch. The nameof(property) operator got rid of magic strings when referencing properties. Obvious win. Extended Property Patterns were a feature I never even knew I wanted...until I had it. Once I started using them, I wondered they never occurred to me.

C# 11 introduces an embarrassment of new features. The language is quite mature so many, if not most, make it more expressive and developer-friendly. Among these, Extended Property Patterns stand out for their ability to enhance pattern-matching capabilities, especially when dealing with complex nested object structures. This article dips into what they are, why they were added, and the gaps in the language they fill. We also cover when and why to use Extended Property Patterns and give you a practical code sample from one of my systems to illustrate their value.

What Are Extended Property Patterns?

Extended Property Patterns allow you to perform pattern matching on nested properties within an object. This means you can directly match on sub-properties of a class, making your code more concise and readable.

bool IsJohnDoe(Person person) =>
    person is { Name: "John", Address.City: "Doe City" };

bool IsJohnDoe(Person person) =>
    person is { Name: "John", Address.City: "Doe City" };

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

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

Here, the pattern { Name: "John", Address.City: "Doe City" } checks if the person object has the Name property set to "John" and the City property of the Address property set to "Doe City".

Why Add Them to C#

Before C# 11, pattern matching on nested properties necessitated additional code and intermediate variables. The old approach was both verbose and less than intuitive. Extended Property Patterns streamline this process, letting developers write readable and easily maintainable code.

The Lack They Fill

Before Extended Property Patterns, matching on nested properties was cumbersome. Consider the old approach:

bool IsJohnDoe(Person person) =>
    person != null &&
    person.Name == "John" &&
    person.Address != null &&
    person.Address.City == "Doe City";
        

It is verbose and error-prone, especially null reference errors. Extended Property Patterns eliminate verbosity and potential errors by providing a direct and clear mechanism to match nested properties.

When to Use Extended Property Patterns

Use Extended Property Patterns when you need to do any of the following:

  1. Match Complex Nested Object Structures: Dealing with objects with multiple levels of properties, Extended Property Patterns matching is clear and concise.
  2. Improve Code Readability: EPP clarifies developer intent, especially beneficial in complex logic.
  3. Reduce Boilerplate Code: Depending on the number of uses in a system, it can vastly reduce the amount of structure-dependent code you need to write and maintain. EPP makes your codebase cleaner and more efficient.
  4. Elegance: Okay, not a tangible benefit but, hey, we are developers. Elegant code makes us smile.

When Not to Use Extended Property Patterns

Avoid using Extended Property Patterns if:

  1. Performance is Critical: Pattern matching involves some overhead. In performance-critical sections of code, traditional methods may be more efficient. How much is open to debate and testing, but sometimes every little tweak helps. If so, use the old ways.
  2. Simplicity is Preferred: If the pattern-matching logic is simple and does not involve nested properties, using Extended Property Patterns might add unnecessary complexity.
  3. Backward Compatibility: If you are working in a mixed environment with older versions of C#, these patterns will not be compatible.

Real-World Example: Matching Geographic Coordinates

Let’s consider a real-world example extracted from a geo distance search capability in a commerce site. The requirement was to match geographic coordinates within specific ranges. Now we could Haversine, Vincenty, or Equirectangular to approximate the answer. But these methods are code-heavy and resource-intensive. Instead we use a simple Location class with Latitude and Longitude properties. When we need to check the location range

public class Location
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

public class Event
{
    public string Name { get; set; }
    public Location Venue { get; set; }
}

bool IsEventInRange(Event e) =>
    e is { Venue.Latitude: >= 40.0 and <= 50.0, Venue.Longitude: >= -80.0 and <= -70.0 };

var event1 = new Event { Name = "Conference", Venue = new Location { Latitude = 45.0, Longitude = -75.0 } };
var event2 = new Event { Name = "Meetup", Venue = new Location { Latitude = 35.0, Longitude = -85.0 } };

Console.WriteLine(IsEventInRange(event1)); // True
Console.WriteLine(IsEventInRange(event2)); // False        

In this example, the pattern { Venue.Latitude: >= 40.0 and <= 50.0, Venue.Longitude: >= -80.0 and <= -70.0 } succinctly checks if the event's venue falls within the specified latitude and longitude range.

Conclusion

Extended Property Patterns in C# 11 enhance and beautify C#'s pattern-matching capabilities. They make working with nested object structures easier and more intuitive. EPP fills a gap in previous versions I did not even recognize as a gap. While not always the best choice, their benefits in terms of code clarity and maintainability make them a valuable addition to the C# developer's toolkit.

要查看或添加评论,请登录

Amram Dworkin的更多文章

社区洞察

其他会员也浏览了