C#相当于Java 8接口中的默认方法

时间:2016-12-19 15:39:40

标签: java c#

我听说在Java 8中,可以灵活地在接口中使用函数定义。我认为我们可以在实现此类接口的所有类中具有此功能的默认状态。

所以,我的问题是,我们今天在C#中有这样的功能吗?微软是否有这方面的计划?

5 个答案:

答案 0 :(得分:3)

更新

默认接口方法是C#8的proposed feature

原始答案

C#没有这个确切的功能,但是Extension Methods解决了在Java中引入默认方法的相同问题。

为了向Java 8中的常见集合引入类似LINQ的函数方法,语言设计者想要一种方法来向Iterable<>等接口添加方法。毕竟,.filter(a -> ...).map(a -> ...)语法比map(filter(a ->...), a2 -> ...)更容易阅读,这是他们刚刚添加实用程序方法时必须要做的事情。然而,仅仅向接口添加方法签名将是一个重大变化,因为任何实现该接口的人都会突然拥有不使用Java 8构建的代码,除非他们实现了新方法。因此,他们开发了默认的实现方法,以便在现有接口上放置新方法不会破坏现有代码。

多年前,C#通过引入扩展方法解决了同样的问题。 Extension方法不是实际更改接口本身,而是简单地使用实用程序类中定义的方法(如.Where().Select()上的IEnumerable<>方法),就好像它一样实际上是在目标对象上。

扩展方法和默认实现的约束使它们在范围上非常相似。每个都有一些优点和缺点,我不会在这里讨论,但实质上它们只是解决同一问题的两种不同方法。

因为它与你的具体问题有关:扩展方法的一个缺点是(静态)它们打破了面向对象代码的一些最佳实践:它们之间可能存在命名冲突,你可以例如,不可靠地覆盖它们。所以通常最好避免它们,除非你有一个不能以任何其他方式轻易解决的问题。如果您只是希望提供方法的默认实现,那么通常最好使用基类,并期望人们扩展您的基类。

我认为你会发现大多数Java专家都会对Java中的Default Implementations说同样的话。它们不是在Java 8之前引入的,因为流行的智慧是接口用于定义一个事物能够做什么而类用于定义如何那些事情已经完成。当然,你总能找到一些smart people who think there's no good reason to have interfaces in the first place。但是,如果您正在使用接口,那么可能是因为您在定义合同时看到了价值而没有提供实现细节。引入了默认实现来解决一个非常具体的向后兼容性问题,如果你可以首先避免这个问题,那么我没有任何理由可以使用它们。

扩展方法同时更危险,更强大,因此除了向后兼容性问题之外,它们还有一些很好的用途,但它们仍应谨慎使用,并且只有在其他更加面向对象的方法获胜时才能使用它们工作。

答案 1 :(得分:3)

此处记录了C#中默认接口实现的官方语言提议:

https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md

目前标有状态为&#34;提案&#34;。

据说,有很多用例,它们非常强大。目前,看起来很有可能被Mass Torgerson和Dustin Campbell在下面的视频中表示批准。如果是这样的话,几乎可以肯定与C#8一起发布。

https://channel9.msdn.com/Events/Build/2017/B8104

大约53:00,讨论开始,并显示演示。

答案 2 :(得分:2)

C#8.0将介绍默认接口实现的新功能。添加新方法以保持与现有接口实现的兼容性时,这非常有用。它还可以提供简单的默认实现,如以下示例所示:

{{1}}

fs.unlinkSync

答案 3 :(得分:1)

我同意迄今为止在评论中所作的陈述--C#并不支持这一点。据我所知,没有计划在C#中支持这一点, 也不支持它。我不同意Java 8,包括这个功能;我认为它混淆了接口和抽象基类。正如@AntP在评论中所说,接口应该是契约(而不是指定行为)。

以下两种可能的设计可以完成同样的事情(对于草率绘制的UML抱歉): enter image description here

基本上,您可以创建一个抽象基类,为所有子类添加默认实现,或者您可以为某些实现接口的子类创建基类(如果& #39; s你正在尝试做什么。

显然其他设计是可能的,这个图主要是为了说明的目的。

答案 4 :(得分:1)

C#不支持这一点,但我不同意接口应该是合同而不是实现的评论。因为默认实现不适用于实现,所以如果他们不使用他们之前使用的新版本api中引入的新方法,那么就不会让客户端无法实现新更新的接口而不会让他们的旧冷却中断。 。

java 8实现中的默认方法确实有助于解决更新api后到达的实际问题。