在 C#8 中,微软为接口方法引入了默认实现。这仍然是一个相当新的功能,似乎有很多相关的博主都在写这个。
我想知道的是,默认实现是否有可能成为依赖倒置和 DI 的有用工具,或者它是否会促进不良的编程风格?它是否违反了任何众所周知的原则,例如 SOLID?
在 C#8 中,微软为接口方法引入了默认实现。这仍然是一个相当新的功能,似乎有很多相关的博主都在写这个。
我想知道的是,默认实现是否有可能成为依赖倒置和 DI 的有用工具,或者它是否会促进不良的编程风格?它是否违反了任何众所周知的原则,例如 SOLID?
默认接口实现有两个主要的设计目标。更重要的是可以追溯到关于设计界面的指南。特别是,一旦你发布了一个界面,它就应该是一成不变的,永远不会改变。问题是,这也是一条一直被忽视的规则。
第一个也是主要的实用程序是默认接口实现允许您将新成员引入接口,而不会破坏与该(公共)接口消费者的源代码或二进制兼容性。这仍然限制了您在更改公共界面时可以进行的更改类型,但也使客户更容易使用新界面 - 升级是免费的,他们可以立即开始使用新功能。
第二个设计目标是用特性扩展类的方法——这在游戏开发中早已被使用。基本思想是,您可以通过让类实现接口来向类添加新的明确定义的行为,同时还保留修改类本身行为的能力。这本质上是一种相对较弱的元编程形式。
当然,仅仅因为这些是设计目标并不意味着它们是您应该使用默认实现的唯一方式。但是如果你概括一下,你会得到这两个基本用途:
事实上,你甚至可以说这比类继承更简单、更清晰、更强大。在某种程度上,这是从扩展方法开始的方法的延续——本质上,默认接口方法实现是一个扩展方法,也是虚拟的。默认实现只能使用公共接口,但实现类也可以使用自己的隐藏状态。它为 C# 提供了一种有限形式的多重继承,而无需处理如何将两个“父级”的状态连接在一起(因为接口没有任何状态)。
最后,如果您担心像 SOLID 这样的原则,让我们试一试: