返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
C#

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?

曦远 (DealiAxy)约 15 分钟
目录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 typeSupportedExample syntax
Instance methodsYespublic void M() => ...
Instance propertiesYespublic int Length => str.Length;
Static methodsYespublic static void Help() => ...
Static propertiesYespublic static string Default => "None";
Operator overloadsYespublic static bool operator +(string a, MyType b)
IndexersYespublic 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 extension block makes the code structure clearer than methods scattered across a static class.
  • Zero breaking changes: The new syntax is fully compatible with the old this extension 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 许可协议。转载请注明出处!

相关文章

并行化优化KD树算法:使用C#实现高效的最近邻搜索

本文介绍了如何使用并行计算技术优化 KD 树算法,并使用 C# 编程语言实现了高效的最近邻搜索。首先,我们简要介绍了 KD 树的原理和构建过程,然后详细讨论了如何利用并行计算库在多个 CPU 核心上并行构建 KD 树,从而加速搜索过程。通过实验验证,我们证明了并行化优化能够显著提高 KD 树的构建速度和搜索效率,为大规模数据集下的最近邻搜索问题提供了一种高效的解决方案。

2024-03-10 · C# · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…