[英]C# equivalent of Java 8 Default Methods in Interface
我听说在Java 8中可以灵活地在接口中使用函数定义。 我认为我们可以在实现此类接口的所有类中具有此功能的默认状态。
那么,我的问题是我们今天在C#中有这样的功能吗? 微软是否有这方面的计划?
默认接口方法是C#8的计划功能 。
C#没有这个确切的功能,但是扩展方法解决了在Java中引入默认方法的相同问题。
为了向Java 8中的公共集合引入类似LINQ的函数方法,语言设计者想要一种方法来向Iterable<>
等Iterable<>
添加方法。 毕竟, .filter(a -> ...).map(a -> ...)
语法比map(filter(a ->...), a2 -> ...)
更容易阅读map(filter(a ->...), a2 -> ...)
如果他们只是添加了实用工具方法,那就是他们必须要做的事情。 然而,仅仅向接口添加方法签名将是一个重大变化,因为任何实现该接口的人都会突然拥有不使用Java 8构建的代码,除非他们实现了新方法。 因此,他们开发了默认的实现方法,以便在现有接口上放置新方法不会破坏现有代码。
几年前,C#通过引入扩展方法解决了同样的问题。 而不是实际更改接口本身,Extension方法只是使得在实用程序类中定义的方法(如IEnumerable<>
上的.Where()
和.Select()
方法.Where()
变得容易,就好像它实际上在目标对象。
扩展方法和默认实现的约束使它们在范围上非常相似。 每个都有一些优点和缺点,我不会在这里讨论,但实质上它们只是解决同一问题的两种不同方法。
因为它与您的具体问题有关:扩展方法的一个缺点是(静态)它们破坏了面向对象代码的一些最佳实践:它们之间可能存在命名冲突,并且您无法覆盖例如,它们是可靠的。 所以通常最好避免它们,除非你有一个不能以任何其他方式轻易解决的问题。 如果您只是希望提供方法的默认实现,那么通常最好使用基类,并期望人们扩展您的基类。
我想你会发现大多数Java专家会对Java中的Default Implementations说同样的话。 他们不是之前的Java 8中引入的,因为当时的看法是,接口都没有定义什么事情能够做到的事情,而类是有定义这些事情是如何完成的。 当然,你总能找到一些聪明的人,他们认为没有充分的理由首先拥有接口 。 但是,如果您正在使用接口,那么可能是因为您在定义合同时看到了价值而没有提供实现细节。 引入了默认实现来解决一个非常具体的向后兼容性问题,如果你可以首先避免这个问题,那么我没有任何理由可以使用它们。
扩展方法同时更危险,更强大,因此除了向后兼容性问题之外,它们还有一些很好的用途,但它们仍应谨慎使用,并且只有在其他更加面向对象的方法不起作用时才能使用。
这里记录了C#中默认接口实现的官方语言提议:
https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md
它目前标有“提案”状态。
话虽如此,它有很多用例,它们非常强大。 目前,看起来很有可能被Mass Torgerson和Dustin Campbell在下面的视频中表示批准。 如果是这样的话,几乎可以肯定与C#8一起发布。
https://channel9.msdn.com/Events/Build/2017/B8104
大约53:00,讨论开始并显示演示。
C#8.0将介绍默认接口实现的新功能。 添加新方法以保持与现有接口实现的兼容性时,这非常有用。 它还可以提供简单的默认实现,如以下示例所示:
public interface ILogger
{
void Log(LogLevel level, string message);
void Log(LogLevel level, string format, params object[] arguments)
{
Log(level, string.Format(format, arguments));
}
}
C#不支持这一点,但我不同意那些说接口应该是契约而不是实现的注释。 因为默认实现不适用于实现,所以如果他们不使用他们之前使用的新版本api中引入的新方法,那么就不会让客户端无法实现新更新的接口。
java 8实现中的默认方法确实有助于解决更新api后到达的实际问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.