Can C# Extension Methods Only Use this? C# 14's New Syntax Takes Extension Methods to a Whole New Level
.NET 10's extension method syntactic sugar? Oh, you define extensions with `extension` blocks, and they support properties and methods now—couldn't before, can now, how novel. Static extension members? A bit late, but adding static methods to `DateTime` can finally be elegant. Upgrade already, or how else are you going to enjoy these new toys?
目录7 个章节
Introduction
PS: Come on, AI programming is everywhere now—why is anyone still studying programming language syntax?
Just kidding, haha. For some simple and highly customized code, writing it by hand is still better. In the time it takes to talk to an AI, I could've already written the code 😄
Recently I've been writing some analysis scripts for StarBlog and needed extension methods to simplify the code. I recalled seeing in the .NET 10 update docs a while back that there's a new extension method syntax. I originally thought it would be like Kotlin, where you no longer need to write a static class—turns out you still do…
But the new syntax is still pretty nice to use.
PS: Even though I write the code myself, I don't have to read the docs anymore—just let AI summarize them 😄
I'll take this opportunity to document the new syntax.
From Static Methods to Extension Blocks
Traditional extension methods require repeating the this parameter on every method, and you can only extend methods. The new syntax uses the extension keyword to define a block, declaring the target type in one place.
The traditional way looks like this
public static class StringExtensions {
// 每个方法都要写一遍 (this string str)
public static bool IsValidEmail(this string str) => str.Contains("@");
public static string ToTitleCase(this string str) => ...;
}
New syntax (C# 14 / .NET 10)
public static class MyExtensions {
// 定义一个针对 string 的扩展块,str 是接收者名称
extension(string str) {
// 1. 扩展属性 (以前做不到)
public bool IsValidEmail => str.Contains("@");
// 2. 扩展方法 (不再需要写 static 和 this)
public string ToTitleCase() => char.ToUpper(str[0]) + str.Substring(1);
}
}
Member Types Supported by the New Syntax
This is the most powerful part of .NET 10—the range of what you can extend has been greatly expanded:
| Member type | Supported | Example syntax |
|---|---|---|
| Instance methods | Yes | public void M() => ... |
| Instance properties | Yes | public int Length => str.Length; |
| Static methods | Yes | public static void Help() => ... |
| Static properties | Yes | public static string Default => "None"; |
| Operator overloads | Yes | public static bool operator +(string a, MyType b) |
| Indexers | Yes | public char this[int i] => str[i]; |
Static Extension Members
Previously we couldn't add static utility methods to an existing class (like DateTime or int). Now we can.
public static class DateTimeExtensions {
// 注意:括号内只有类型,没有实例名称,表示静态扩展
extension(DateTime) {
public static DateTime Tomorrow => DateTime.Now.AddDays(1);
}
}
// 使用时:
var nextDay = DateTime.Tomorrow; // 就像 DateTime 原生自带的一样
Generic Support
The new syntax's support for generics is very elegant, especially when working with collections (LINQ-style):
public static class EnumerableExtensions {
extension<T>(IEnumerable<T> source) {
// 扩展属性:判断集合是否为空
public bool IsEmpty => !source.Any();
// 扩展方法
public void ForEach(Action<T> action) {
foreach (var item in source) action(item);
}
}
}
Actual Code
Since I mentioned these are scripts written for StarBlog, I might as well share the actual code I used (padding the word count (not really))
It's actually an extension method that extracts the paragraph under a markdown second-level heading
public static class MyExtensions {
extension(Post post) {
public string GetSection(string title) {
return ExtractSectionRegex(post.Content, title);
}
public Dictionary<string, string> GetSections(params string[] titles) {
var dict = new Dictionary<string, string>();
foreach (var title in titles) {
dict.Add(title, post.GetSection(title));
}
return dict;
}
}
private static string ExtractSectionRegex(string content, string title) {
// 匹配目标标题开始,直到下一个标题或文档末尾
string pattern = $@"##\s*{title}\s*([\s\S]*?)(?=\n##|$)";
var match = Regex.Match(content, pattern);
return match.Success ? match.Groups[1].Value.Trim() : string.Empty;
}
}
This GetSections method can actually be simplified further with LINQ syntax
public Dictionary<string, string> GetSections(params string[] titles) {
return titles.ToDictionary(title => title, title => post.GetSection(title));
}
Then simplify it again with a method group, and the final result is
public Dictionary<string, string> GetSections(params string[] titles) {
return titles.ToDictionary(title => title, post.GetSection);
}
Now THAT's what you call elegant?! 🐸
Wrap-up
The new extension syntactic sugar is pretty sweet. As I see it, there are a few advantages:
- More natural code: Extension properties make the API look more like a native part of the target type, rather than having to call a method with parentheses.
- Logic in one place: Defining all related extensions in a single
extensionblock makes the code structure clearer than methods scattered across a static class. - Zero breaking changes: The new syntax is fully compatible with the old
thisextension method syntax, so you can mix them as you like.
Note: These new features are only available if you have the .NET 10 SDK installed and set <LangVersion> to 14.0 or preview in your project file.
So hurry up and upgrade all your projects to .NET 10 😄
PS: This StarBlog project of mine has been upgraded all the way from .NET 6 to .NET 10—it's a project with a bit of history at this point 🤣
_EOF_
Can C# Extension Methods Only Use this? C# 14's New Syntax Takes Extension Methods to a Whole New Level
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
开发现代化的.NetCore控制台程序:(1)项目介绍以及依赖注入/配置/日志等使用细节
开发.NET Core控制台工具,依赖注入和日志整合得比Go优雅多了。哼,配置文件丝滑,但AOT?反射问题,放弃。
2023-11-10 · C# · 约 1 分钟
纯 C#实现+AOT 打造的多功能图片处理工具 ImageGlider
纯C#+AOT打造的ImageGlider,图像处理功能堆得像山,还非得标榜零依赖?ImageSharp封装得倒是挺顺溜,就是不知道这模块化架构能走多远。Web API和CLI工具有点东西,但别指望我夸太离谱。
2025-08-05 · C# · 约 1 分钟
C#集成ViewFaceCore人脸检测识别库
人脸检测与识别现在已经很成熟了,C# 上有 ViewFaceCore 这个很方便的库,但这种涉及到 native 调用的库,一般会有一些坑,本文记录一下开发和部署的过程。
2023-09-20 · C# · 约 1 分钟
C#移除字符串中的不可见Unicode字符
背景 最近发现某个数据采集的系统拿下来的数据,有些字段的JSON被莫名截断了,导致后续数据分析的时候解析JSON失败。 类似这样 {title: 你好 或者这样,多了个双引号啥的 {title:你好} 因为数据库是Oracle,起初以为是Oracle这老古董出问题了,结果一番折腾,把每条写入数据的SQL语句都拿出来,看起来里面的JSON格式都没问题。 这也太诡异了吧,看起来没毛病,但就为啥JSON
2023-02-02 · C# · 约 1 分钟
讨论
共 0 条加载评论中…