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.
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.
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.");
}
}
}
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.");
}
}
}
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.");
}
}
}
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);
}
}
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.");
}
}
}
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.");
}
}
}
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.");
}
}
}
Here are some best practices to follow when using extended property patterns in C#:
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.");
}
}
}
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.");
}
}
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.");
}
}
}
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.");
}
}
}
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.