扩展方法能够应用于接口吗?

169

能否将扩展方法应用于接口?(C#问题)

例如,实现以下功能:

  1. 创建一个ITopology接口。

  2. 为此接口创建一个扩展方法(例如:public static int CountNodes(this ITopology topologyIf))。

  3. 当创建实现ITopology接口的类(例如:MyGraph)时,它会自动拥有Count Nodes扩展方法。

这样就不需要让实现该接口的类与扩展方法中定义的设置类名称相对应。

1个回答

235
当然可以;大多数 Linq 是围绕接口扩展方法构建的。
实际上,接口是扩展方法开发的推动力之一;由于它们不能实现任何自己的功能,因此扩展方法是将实际代码与接口定义关联的最简单方法。
请参见 Enumerable 类,其中包含围绕 IEnumerable<T> 构建的整个扩展方法集合。 要实现一个扩展方法,与为类实现相同:
public static class TopologyExtensions
{
    public static void CountNodes(this ITopology topology)
    {
        // ...
    }
}

就接口而言,扩展方法没有什么特别的不同之处;扩展方法只是一个静态方法,编译器会对其应用一些语法糖,使其看起来像是目标类型的一部分。


51
回复:“当然” - 我认为这个问题揭示了你隐含提到的架构气味。如果接口可以扩展,为什么接口不能包含实现方法?可以理解为认为接口应该能够具有具体方法,或者一旦知道它们不能,就认为扩展方法不应该作为可行的权宜之计。(但它们确实是。不是在质疑您出色的答案,只是“当然”和链接到IEnum而不是LINQ可能需要澄清。;^D)有些怪异的地方! - ruffin
6
现在你可以在C#接口方法中添加默认实现,这是对@ruffin评论的补充。来源:https://devblogs.microsoft.com/dotnet/default-implementations-in-interfaces/ - Vinigas
2
@ruffin 我认为这是 C# 中最令人困惑的架构决策。有时它会变成一半类一半接口的结构,让人感到混乱。不过,我相信从函数式编程的角度来看,它可能会有用,并且可用于将实用程序引入接口而不是实现功能。 - Guney Ozsan
@ruffin 还有另一个优势。如果你正在使用库(原则上,当使用库时应该使用接口),扩展提供了覆盖它的机会,对吧?而接口不能有“虚拟”方法(好吧,在C# 8中,你可以声明一个主体,它们可以)。所以,这是一个强大的选项。再次强调,这只是一个选项,它只是武器库中的一种。从这个角度来看,这是一件令人难以置信的事情,不是吗? - Ergis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接