惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Latest news
Latest news
爱范儿
爱范儿
V
V2EX
J
Java Code Geeks
I
InfoQ
博客园 - 三生石上(FineUI控件)
V
Visual Studio Blog
A
Arctic Wolf
月光博客
月光博客
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
Cisco Talos Blog
Cisco Talos Blog
量子位
C
CERT Recently Published Vulnerability Notes
Know Your Adversary
Know Your Adversary
酷 壳 – CoolShell
酷 壳 – CoolShell
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
小众软件
小众软件
Hugging Face - Blog
Hugging Face - Blog
P
Privacy & Cybersecurity Law Blog
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
T
The Exploit Database - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Scott Helme
Scott Helme
C
Cisco Blogs
T
Tor Project blog
I
Intezer
Project Zero
Project Zero
罗磊的独立博客
T
Tenable Blog
Jina AI
Jina AI
P
Proofpoint News Feed
T
Threatpost
NISL@THU
NISL@THU
N
News and Events Feed by Topic
Engineering at Meta
Engineering at Meta
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AI
AI
Recorded Future
Recorded Future
T
Tailwind CSS Blog
T
The Blog of Author Tim Ferriss
S
Security @ Cisco Blogs
云风的 BLOG
云风的 BLOG
N
News | PayPal Newsroom

博客园 - 曦远Code

给热水器装上“电量显示”:用 Shelly Gen4 脚本实现零改装水量预测 StarBlog番外(5) 从1.6到1.10,基于Avalonia AOT 开发的 Publisher 半年进化之路 你的显卡能跑多少算子?用 55 个检查项,给 PyTorch GPU 环境做一次冒烟测试 ROCm on Windows 性能排查:RX 6650 XT 跑 PyTorch,为什么加速不明显? lighthouse-fw:一个管理腾讯云轻量服务器防火墙的终端工具 用本地大模型驱动中文输入法,我做了一个实验性的项目 Spark.NET:一个试图把 Django / Rails 式开发体验带回 .NET 世界的全栈 Web 框架。 Zed AI 白嫖免费模型,搭配 DeepSeek v4,玩转 Agent 编程技巧 当 CGO 遇见 Zig:一种更优雅的折腾方式,对比 GCC 后端 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf 后 Django 时代:SQLAlchemy 2.0、Tortoise 与 Piccolo 三大异步 ORM 选型指南 Python网络请求库,从 requests 到 httpx 浅谈次世代代码编辑器 Zed:Rust 原生性能、GPU 渲染 现代 Python 程序优雅处理日期时间的避坑指南 你的SSH密钥可能已经过期了 是谁 2026 年还在用 Sublime Text 写代码? 什么年代了怎么还在用bash啊?现代化shell开箱体验: fish, nu, elvish 别再手动复制SSH公钥了,Linux服务器一键从GitHub快速导入公钥 2026年的Linux桌面环境选择,哪些适合Debian服务器? 在 Windows 11 上使用 Hyper-V 虚拟机准备安装OpenClaw 经历分享,发现挖矿木马后,服务器快速备份与重装(腾讯云平台) Coolify: Vercel 的开源版私有化部署平替版 分享一些2026年有意思的现代化Django生态组件 实测 Django 6.0:模版片段、后台任务、CSP 安全,三大特性体验报告 当人人都能用 AI 写代码时,我为什么选择重回 Django? 打包ROCm环境的相关Wheel方便后续使用 从挖矿木马入侵到 Docker Rootless 加固,我的服务器安全复盘 AMD显卡也能畅玩AI画图!ROCm+ComfyUI部署全指南
C# 扩展方法只会写 this 吗?C# 14 新语法直接把扩展方法玩出了花
曦远Code · 2026-03-10 · via 博客园 - 曦远Code

前言

PS: 不是,AI编程都普及了,怎么还有人研究编程语言的语法?

开个玩笑哈哈,一些简单和定制性比较强的代码还是手写比较好,有和AI对话的时间,我都把代码写好了😄

最近我在给 StarBlog 写一些分析脚本,需要用到扩展方法来简化代码,我想到前段时间看到 .NET10 的更新文档说有新的扩展方法语法,我本来以为是和 Kotlin 一样不再需要写一个静态类了,结果还是要…

不过新的写法还挺好用的。

PS: 虽然代码是自己写的,但文档不用自己看了,直接让AI总结😄

正好借本文记录一下这个新的写法。

从静态方法到扩展块

传统的扩展方法需要每个方法都重复写 this 参数,且只能扩展方法。新语法通过 extension 关键字定义一个块,将目标类型集中声明。

传统写法是这样的

public static class StringExtensions {
    // 每个方法都要写一遍 (this string str)
    public static bool IsValidEmail(this string str) => str.Contains("@");
    public static string ToTitleCase(this string str) => ...;
}

新语法(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);
    }
}

新语法支持的成员类型

这是 .NET 10 最强大的地方,扩展的能力范围极大地拓宽了:

成员类型 是否支持 示例语法
实例方法 public void M() => ...
实例属性 public int Length => str.Length;
静态方法 public static void Help() => ...
静态属性 public static string Default => "None";
运算符重载 public static bool operator +(string a, MyType b)
索引器 public char this[int i] => str[i];

静态扩展成员

以前我们无法给一个现有的类(比如 DateTimeint)添加静态工具方法,现在可以了。

public static class DateTimeExtensions {
    // 注意:括号内只有类型,没有实例名称,表示静态扩展
    extension(DateTime) {
        public static DateTime Tomorrow => DateTime.Now.AddDays(1);
    }
}

// 使用时:
var nextDay = DateTime.Tomorrow; // 就像 DateTime 原生自带的一样

泛型支持

新语法对泛型的支持非常优雅,尤其是在处理集合(LINQ 风格)时:

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);
        }
    }
}

实际代码

既然说到是给 StarBlog 写的脚本,那我也把实际用到的代码放出来吧 (水字数(bushi)

实际上是一个提取 markdown 二级标题下段落的扩展方法

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;
    }
}

实际上这个 GetSections 方法又可以用 LINQ 语法简化一下

public Dictionary<string, string> GetSections(params string[] titles) {
    return titles.ToDictionary(title => title, title => post.GetSection(title));
}

再用 method group 简化一下,最终效果

public Dictionary<string, string> GetSections(params string[] titles) {
    return titles.ToDictionary(title => title, post.GetSection);
}

翻译翻译,什么叫优雅?!🐸

小结

新的扩展语法糖还是很甜的,在我看来有几个优势:

  • 代码更自然:扩展属性让 API 看起来更像目标类型的原生一部分,而不是非要调用一个带括号的方法。
  • 逻辑集中:在一个 extension 块里定义所有相关的扩展,代码结构比散落在静态类里的方法更清晰。
  • 零破坏性:新语法与旧的 this 扩展方法语法完全兼容,可以根据喜好混合使用。

注意: 只有安装了 .NET 10 SDK 并在项目文件中将 <LangVersion> 设置为 14.0preview,才能使用这些新特性。

所以赶紧把项目都升级到 .NET10 把😄

PS: 我这个 StarBlog 项目一路从 .NET6 升级到 .NET10,也算是有点历史的项目了🤣

微信公众号:「程序设计实验室」 专注于互联网热门新技术探索与团队敏捷开发实践,包括架构设计、机器学习与数据分析算法、移动端开发、Linux、Web前后端开发等,欢迎一起探讨技术,分享学习实践经验。