同一名称空间中的类和扩展方法容器类.有什么好处?

Moh*_*min 3 c# extension-methods nbuilder

我在单元测试中尝试NBuilder.一个很棒的图书馆 但是,我无法解释类和接口的以下结构.

  • FizzWare.NBuilder名称空间中

    • ISingleObjectBuilder
    • SingleObjectBuilderExtensions
  • FizzWare.NBuilder.Implementation

    • IObjectBuilder`
    • ObjectBuilder
  • SingleObjectBuilderExtensions只是一个包装IObjectBuilder.

  • 客户端代码通常应该使用一个名为的类,该类Builder具有一个静态方法ISingleObjectBuilder.您永远不需要在客户端代码中实例化任何类.

现在,我不明白了SingleObjectBuilderExtensions.它是否具有任何设计效益?ISingleObjectBuilder当两个接口在同一名称空间中时,为什么不直接使用这些方法.

Mar*_*ell 8

ISingleObjectBuilder是一个界面; 接口无法提供实现.这意味着每个实施ISingleObjectBuilder都需要提供实施.

但是,在许多情况下,方法具有预定义的行为,并且只需要访问接口的其他成员(即只是成员ISingleObjectBuilder),因此使每个实现提供此功能没有任何好处.

此外,将更多成员添加到现有接口并不是一个好主意,因为这对所有现有实现都是一个重大变化.

扩展方法解决了这两个问题:

  1. 扩展方法适用于所有实现 ISingleObjectBuilder
  2. 它不会更改现有的API,因此所有现有的实现都将继续有效

将它放在同一个命名空间中只是简单方便.可能的赌注是,任何ISingleObjectBuilder已经使用的代码都有一个using导入该命名空间的指令; 因此,大多数代码已经只需按下看到IDE扩展方法.在IDE中.

要添加具体示例,LINQ-to-Objects可以使用IEnumerable<T>.有很多IEnumerable<T>实现.如果每个人都不得不自己写First(...),FirstOrDefault(...),Any(...),Select(...)等方法,这将是一个巨大的负担-机器人将提供无以效益为实现将在大多数情况下几乎是相同的.另外,回顾性地将其安装到界面上将是灾难性的.

作为旁注:方法的per-type版本总是优先于扩展方法,所以如果(在LINQ-to-Objects的情况下)你有一个实现IEnumerable<T>(对于某些T)的类型,并且该类型有一个.First()实例方法, 然后:

YourType foo = ...
var first = foo.First();
Run Code Online (Sandbox Code Playgroud)

将使用您的版本,而不是扩展方法.