C# 14扩展成员功能彻底革新:告别半成品的扩展方法时代!

作者:微信公众号:【架构师老卢】
9-7 18:7
13

你是否曾有过这样的感觉——使用了多年的某个功能突然显得……不完整?这就是我一直对扩展方法的感受。它们确实很巧妙,但从未真正融入语言体系。它们就像是戴着整洁语法面具的临时解决方案。

C# 14刚刚通过扩展成员(Extension Members) 解决了这个问题。我现在就要断言:这是整个版本中最好的功能。

让我告诉你为什么。

扩展方法始终是半成品

我从不讨厌扩展方法。它们很有用。但说实话,它们总是让人觉得语言在说:

"嘿,我们知道你想在不修改源码的情况下扩展API,所以这里有一个伪装成更酷东西的静态方法。别看得太仔细。"

而你确实仔细看了,不是吗?

  • 不能添加属性
  • 不能添加运算符
  • 除了笨拙的静态类之外,无法对相关扩展进行逻辑分组
  • 它们从未真正感觉像是类型的一部分

现在有了扩展成员——这是扩展方法一直想要成为的成熟版本。

示例1:经典的ToObservable重写

如果你使用过MVVM模式(WPF、Xamarin、MAUI等),可能已经写过上百次这样的代码:

public static class ObservableExtensions
{
    public static ObservableCollection<T> ToObservable<T>(this IEnumerable<T> source)
        => new ObservableCollection<T>(source);
}

它能用,但感觉很别扭;它不像是对现有类型的扩展。现在来看看扩展成员的方式:

public static class EnumerableExtensions
{
    extension(IEnumerable<T> collection)
    {
        public ObservableCollection<T> ToObservable()
            => new ObservableCollection<T>(collection);
    }
}

看到区别了吗?没有杂乱代码。没有奇怪的"静态方法假装成真实成员"。感觉就像IEnumerable<T>本身就拥有这个行为。如果你在职业生涯中使用过Swift,可能会对这个功能深有感触,我理解,这简直是🤌(完美)

语法速览:扩展成员一览

如果你想掌握这个语法:

public static class NameOfExtensionClass
{
    extension(YourType obj)
    {
        // 方法、属性、运算符,甚至嵌套类型
    }
}

是的,你没看错,允许使用属性和运算符。

示例2:添加真正有意义的属性

是否曾想要一种简洁的方法来检查集合是否为空,而不必到处写!collection.Any()collection.Count == 0

使用扩展成员:

public static class CollectionExtensions
{
    extension(ICollection<T> collection)
    {
       public bool IsEmpty => this.Count == 0;
    }
}

用法:

if (myList.IsEmpty)
{
    // 终于以应有的方式阅读代码了
}

这是扩展方法永远无法优雅实现的事情;现在它感觉像是类型系统的自然组成部分。

示例3:静态扩展成员

你甚至可以向不拥有的类型添加静态成员:

public static class DateTimeExtensions
{
    extension(DateTime)
    {
        public static DateTime UnixEpoch => new DateTime(1970, 1, 1);
    }
}

迁移现有代码

有一整个静态扩展方法库?可以这样迁移:

之前:

public static class DateTimeExtensions
{
    public static bool IsWeekend(this DateTime date)
        => date.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday;
}

之后:

public static class DateTimeExtensions
{
    extension(DateTime dateTime)
    {
        public bool IsWeekend => dateTime.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday;
    }
}

更简洁。更易发现。更易维护。

底层工作原理

对于好奇的读者,这里简单说明:

  • 它们不修改原始类型
  • 编译器和元数据将它们视为"附加"成员
  • 工具(如IntelliSense)将它们显示为好像属于该类型
  • 底层仍然是安全且分离的,只是更智能

想让我深入探讨机制吗?在评论区留言,我可能会专门写一篇文章。

需要了解的局限性

它们是新功能,所以:

  • 没有运行时魔法,仅编译时有效
  • 不能添加字段或操作私有成员
  • 现代IDE之外的工具可能暂时支持滞后

但说实话?相对于我们获得的功能,这些都是次要的权衡。

为什么这是我最喜欢的功能

扩展成员终于让扩展感觉像是一等公民。它们让API自然演进。它们减少了代码杂乱。它们让代码读起来就像原本就是这样设计的。

这不仅仅是语法糖。这是让我对重构旧代码库感到兴奋的功能——我不常这么说。

扩展成员不仅仅是一个闪亮的新语法。它们是一次课程修正。它们完成了扩展方法开始的工作。更简洁的API、可发现的功能、隐藏在随机命名空间中的工具类更少,这一切都感觉……恰到好处。

这就是为什么这是我最喜欢的C# 14功能。它不会让你重新思考如何编写部分代码,而是让你重新思考如何设计所有代码。

现在轮到你了:你首先会将什么重构为扩展类型?你会全力以赴迁移所有辅助类,还是用一个杀手级属性来试水?在评论区告诉我,我想看看你的想法。

如果我遗漏了什么,请在评论区补充。另外,如果你发现博客中有任何不正确的地方,也请在评论区指正。

相关留言评论
昵称:
邮箱:
阅读排行