我正在尝试 NBuilder在我的单元测试中。一个优秀的图书馆。但是,我无法解释以下类和接口(interface)的结构。
在
FizzWare.NBuilder
命名空间中:ISingleObjectBuilder
SingleObjectBuilderExtensions
在
中FizzWare.NBuilder.Implementation
- IObjectBuilder`
ObjectBuilder
SingleObjectBuilderExtensions
只是IObjectBuilder
的包装器。客户端代码通常应使用名为
Builder
的类,该类具有为您提供ISingleObjectBuilder
的静态方法。您永远不需要在客户端代码中实例化任何类。
现在,我不明白 SingleObjectBuilderExtensions
的意义。它会带来任何设计好处吗?为什么不将这些方法直接放在 ISingleObjectBuilder
中,特别是当两个接口(interface)位于同一命名空间中时。
最佳答案
ISingleObjectBuilder
是一个接口(interface);接口(interface)不能提供实现。这意味着 ISingleObjectBuilder
的每个实现需要提供实现。
但是,在许多情况下,一个方法具有预定义的行为,并且只需要访问接口(interface)的其他成员(即仅是 ISingleObjectBuilder
的成员),因此让每个实现都提供此行为没有任何好处。
此外,向现有接口(interface)添加更多成员不是一个好主意,因为这对所有现有实现来说都是一个重大改变。
扩展方法解决了这两个问题:
- 扩展方法适用于
ISingleObjectBuilder
的所有实现 - 它不会改变现有的 API,因此所有现有的实现将继续有效
将它放在同一个命名空间中会方便很多。可以肯定的是,任何使用 ISingleObjectBuilder
的代码已经有一个 using
导入该命名空间的指令;因此,只需按 .
,大多数代码已经在 IDE 中看到扩展方法。在 IDE 中。
要添加一个具体示例,LINQ-to-Objects 适用于 IEnumerable<T>
. IEnumerable<T>
有很多实现。如果他们每个人都必须自己写 First(...)
, FirstOrDefault(...)
, Any(...)
, Select(...)
等方法,这将是一个巨大的负担 - 机器人不会提供任何好处,因为在大多数情况下,实现几乎是相同的。此外,追溯地将其安装到界面上将是灾难性的。
作为旁注:方法的per-type版本总是优先于扩展方法,所以if(在LINQ-to-Objects) 你有一个实现了 IEnumerable<T>
的类型(对于某些 T
),并且该类型具有 .First()
实例方法,然后:
YourType foo = ...
var first = foo.First();
将使用您的版本,而不是扩展方法。
关于c# - 同一命名空间中的类和扩展方法容器类。有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11823977/