C#13: Introduction to the extension types.
developrec
We're a leading contributor to the software engineering community & an award-winning recruitment business.
Welcome back to our newsletter!
This edition will guide you through the latest advancements in the .NET world, focusing on the new feature of extension types.
Let's dive in!
C# 13 introduces a significant enhancement called extension types, building on the concept of extension methods introduced in C# 3. Extension methods allow developers to add new methods to existing types without modifying their original code, with LINQ methods on IEnumerable<T> being a prime example.
Extension types expand this capability by adding methods, properties, and other members to an underlying type. These members can be either instance or static, though instance extension types cannot hold state and can only access the state of the underlying type or from another location.
There are two kinds of extension types: implicit and explicit. Implicit extension types apply automatically to all instances of the underlying type, functioning similarly to how current extension methods work. Explicit extension types, on the other hand, only apply when the underlying type is explicitly converted to the extension type. This allows for more controlled and specific extensions of functionality.
Extension types are particularly useful in scenarios where you need to extend the functionality of a type but cannot modify its original code. They offer a way to enhance and customize types flexibly, providing both broad and specific enhancements through implicit and explicit extension types respectively. This new feature in C# 13 represents a significant step forward in the language's evolution, offering more powerful and versatile tools for developers.
Let's look at the examples put forward by Microsoft:
public class Person()
{
public required string GivenName { get; init; }
public required string SurName { get; init; }
public required Organization Organization { get; init; }
}
public class Organization()
{
public required string Name { get; init; }
public required List<Team> Teams { get; init; }
}
public class Team()
{
public required string TeamName { get; init; }
public required Person Lead { get; init; }
public required IEnumerable<Person> Members { get; init; }
}
Instead of repeatedly writing LINQ code to check if a Person is a lead, an extension method can be created. This method can be controlled through namespaces for access management. Alternatively, an implicit extension type can be used to organise extensions for the Person class, providing an IsLead property directly to all Person instances. This approach streamlines the process, making the code cleaner and more efficient.
public implicit extension PersonExtension for Person
{
public bool IsLead
=> this.Organization
.Teams
.Any(team => team.Lead == this);
}
if (person.IsLead) { ... }
Explicit extensions allow for adding extra features to specific instances of a type. For example, to find out which teams a person leads, an explicit extension can be used. This extension would provide the Teams property only to those instances that are leads, making the feature specific and targeted.
领英推荐
public explicit extension Lead for Person
{
public IEnumerable<Team> Teams
=> this.Organization
.Teams
.Where(team => team.Lead == this);
}
Both implicit and explicit extension types support static and instance members, which is great for setting scenario-specific defaults. For example, if there’s only one organization, it’s tedious to specify it every time a person is created. Extension types can offer a default value, making the process more efficient and the code cleaner.
public implicit extension OrganizationExtension for Organization
{
private static Organization ourOrganization = new Organization("C# Design");
public static Person CreatePerson(string givenName, string surName)
=> new(givenName, surName, ourOrganization);
}
Putting this together:
var mads = Organization.CreatePerson("Mads", "Torgersen");
// code to add more people and teams
if (mads.IsLead)
{
Lead madsAsLead = mads;
PrintReport(madsAsLead.Teams);
}
Extension types simplify your application's critical code by organising and customising extensions for specific instances of underlying objects. Technically, they enhance the extension methods you're already familiar with. You can explore them in an upcoming preview of C# 13.
This is just a brief overview of our current work. More detailed posts will follow as features are completed. For a comprehensive list of what we're working on, visit the Roslyn feature status page.
Learn more about these features in Mads Torgersen and Dustin Campbell’s talk, "What’s New in C# 13" at Microsoft Build.