This page shows the source for this entry, with WebCore formatting language tags and attributes highlighted.

Title

Swift protocol extensions for C#

Description

<img attachment="extension_syntax_in_c_14.webp" align="right" caption="Extension syntax in C#14">Since this feature is being touted for C# 14---this time it's coming for real!---I thought it would be good to refresh what I'd already learned about it. The title is a bit hyperbolic but it's quite an interesting feature. It's basically <c>protocol extension</c> from Swift for C#. It's .NET's answer to extending extension methods to properties and, probably, operators. You can't add state, as far as I can tell. But that isn't so surprising. The video below discuss the proposal as it looked for C#13. The pages <a href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#extension-members">What's new in C# 14: Extension members</a> and <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extension">Extension declaration (C# Reference)</a> offer more insight into the current shape of the feature. It seems like they mean it this time and that it will land in November 2025. <media author="Nick Chapsas" source="YouTube" href="https://www.youtube.com/watch?v=ueO5Cb3Emcw" src="https://www.youtube.com/v/ueO5Cb3Emcw" width="560px" caption="The Insane C# 13 Feature That Changes Everything"> What it primarily is, though, is further work on making it easier to transition APIs. We got the first batch of support with default interface implementations. This feature will allow to smooth migrations even more. They will also allow us to "add" properties to types that then introduce their own version of those properties in future versions but that's OK, I think. It means that every added property will be a potential breaking change for someone but maybe it will make us start categorizing breaking changes. There are <c>implicit</c> extensions, which are pretty much a new way of defining extension methods, but with support for proprties. The following example shows how the property <c>IsLead</c> will be available for any <c>Person</c> without modifying that type. This doesn't seem much different than existing extension methods, other than support for properties, where the <c>this</c> keyword stands in for the parameter that would otherwise have been passed in a classic extension method. <code>public implicit extension PersonExtension for Person { public bool IsLead => this.Organization .Teams .Any(team => team.Lead == this); }</code> There are also <c>explicit</c> extensions, which are a way of specifying extensions to types that are neither implemented nor inherited, but are instead given to a type without coercion. That is, you can define a type that can be applied to another type (e.g., <c>Lead</c> for <c>Person</c> in the example below), which makes more methods and properties available. It's kind of confusing without an example. <code>public explicit extension Lead for Person { public IEnumerable<team> Teams => this.Organization .Teams .Where(team => team.Lead == this); } var person = new Person(); var personTeams = person.Teams; // <span class="error">Compile error</span> Lead lead = person; var leadTeams = lead.Teams; // <hl>OK</hl> </code> While this might look like a cast, it's not, because <c>Person</c> doesn't implement <c>Lead</c>---it's <i>extended</i> by <c>Lead</c> in code that isn't necessarily associated with the code that defines <c>Person</c>. In the latest syntax, the example above would look a bit different but the idea is the same. It looks like they've simplified it a bit. <code>public static class PersonExtension { extension(Person source) { public bool IsLead => source.Organization .Teams .Any(team => team.Lead == this);; } }</code> <ul> There a talk called <a source="Microsoft Build" href="https://build.microsoft.com/en-US/sessions/689e5104-72e9-4d02-bb52-77676d1ec5bc?source=sessions" author="Mads Torgersen and Dustin Campbell">What’s new in C# 13</a> for which you have to register. The video will probably come out later on YouTube, though. There's the original <a href="https://github.com/dotnet/csharplang/issues/5497" source="GitHub">[Proposal]: Extensions #5497</a> The most informative link (so far) is <a href="https://devblogs.microsoft.com/dotnet/dotnet-build-2024-announcements/#c-13:%7E:text=best%20concrete%20type.-,Extension%20types,-Extension%20types%20aren%E2%80%99t#extension-types" source="Microsoft Dev Blogs" author=".NET Team">.NET Announcements and Updates from Microsoft Build 2024</a> </ul>