C#8默认实现和依赖倒置

乔希

在C#8中,Microsoft为接口方法引入了默认实现。它仍然是一个相当新的功能,似乎有许多相关的博客写此。

我想知道的是,默认实现是否有可能成为依赖倒置和DI的有用工具,或者它会促进不良的编程风格?它是否违反SOLID等任何众所周知的原则?

a安

默认接口实现有两个主要设计目标。更重要的是一直回到有关设计接口的准则。特别是,一旦发布接口,就应该将其设置固定状态,并且永远不要更改。问题是,这也是所有时间都忽略的规则。

第一个也是主要的实用程序是,默认接口实现允许您将新成员引入接口,而不会破坏与该(公共)接口的使用者的源代码或二进制兼容性。这仍然限制了您在更改公共界面时可以进行的更改的种类,而且还使客户端可以更轻松地使用新界面-升级是免费的,他们可以立即开始使用新功能。

第二个设计目标是一种扩展具有特征的类的方法-这种方法早已在游戏开发中使用。基本思想是,您可以通过使类实现一个接口来向其添加明确定义的新行为,同时还保留在类本身中修改行为的能力。这本质上是元编程的一种相对较弱的形式。

当然,仅因为这些是设计目标,并不意味着它们是应该使用默认实现的唯一方法。但是,如果概括一下,您将获得以下两个基本用途:

  • 在不破坏兼容性的情况下扩展接口,而不必对接口进行版本控制。
  • 扩展类而不必创建从类继承中获得的刚性树层次结构。

实际上,您甚至可以争辩说,这比类继承既简单,清晰又强大。在某种程度上,这是从扩展方法开始的方法的延续-本质上,默认接口方法实现是一种扩展方法,它也是虚拟的。默认实现只能与公共接口一起使用,但是实现类也可以使用其自己的隐藏状态。它为C#提供了有限的多重继承形式,而不必处理两个“父”的状态如何结合在一起(因为接口没有任何状态)。

最后,如果您担心诸如SOLID之类的原则,那就让我们开始吧:

  • SRP-没有真正的改变,有一些新的选择,可以在一处无损地增加新的逻辑。我说这对于SRP来说是一个小小的胜利。
  • OCP-只要扩展类实现了新功能有意义的接口,您就可以得到扩展类的强大新方法,而无需修改类本身。但是您不能以这种方式更改现有类的行为,因此仍然无法进行修改。在这里相当有用的获胜。
  • LSP-没有真正的影响。仅通过实现一个接口(允许您根据需要覆盖该行为的选项)就可以向类添加新的可替代行为,这是一些次要的胜利。
  • ISP-这可以双向进行。如果您具有合理的默认实现,则默认实现可能会更容易拥有许多小型接口。但是它们也可以鼓励您继续修改现有接口,而不是添加新接口。
  • DIP-大多数不受影响。如果新的抽象是对现有内容的合理扩展,或者可以在不依赖状态的情况下实现默认行为,则可以更轻松地添加新的抽象。您也可能会尝试将默认行为用作合同约定,但是IMO仍然比抽象方法(您也可以控制状态)中的诱惑要小。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C#8默认接口实现/特性的事件继承

来自分类Dev

C#8从具体类型内调用默认实现

来自分类Dev

利用C#8索引和范围

来自分类Dev

使成员成为虚拟成员可防止调用默认接口实现,并在C#8中导致StackOverflowException

来自分类Dev

依赖倒置和渴望加载

来自分类Dev

依赖倒置和渴望加载

来自分类Dev

C#8空值和结果容器

来自分类Dev

观察者模式和依赖倒置

来自分类Dev

在接口C#8中使用静态,内部和受保护的访问修饰符

来自分类Dev

C#8不可为空的引用和隐式用法

来自分类Dev

C#8异步流与REST / RPC

来自分类Dev

c#8中的公共接口成员

来自分类Dev

快速依赖倒置

来自分类Dev

K8S中的默认CRI实现和默认CNI实现

来自分类Dev

依赖倒置原理:试图理解

来自分类Dev

依赖倒置设计选择问题

来自分类Dev

依赖倒置原理:试图理解

来自分类Dev

设置层之间的依赖倒置

来自分类Dev

.NET Framework 4.7.2中的C#8功能

来自分类Dev

C#8使用实用程序方法验证参数

来自分类Dev

什么是C#8中的未知可空性?

来自分类Dev

开关表达式中的多个语句:C#8

来自分类Dev

在C#8中使用不带变量的语句

来自分类Dev

C#8开关内的表达式

来自分类Dev

无效方法的C#8开关表达式

来自分类Dev

什么是Kotlin等效于C#8的异步枚举?

来自分类Dev

依赖倒置中的“倒置”是什么意思

来自分类Dev

C#8可为空和不可为空的引用类型-仅当输入为可为空时才可为可输出

来自分类Dev

C#8可为空和不可为空的引用类型-仅当输入为可为空时才可为可输出