Autofixture Fixture.Customize - 为什么重载有不同的 return 类型?

Autofixure Fixture.Customize - why do the overloads have different return types?

我想知道为什么泛型 Customize 重载 returns void 并且似乎在非泛型重载时改变夹具,这需要一个实例ICustomization、returns 和 IFixture?

// you cannot set this var, customize returns void
var configuredFixture = fixture.Customize<whatever>(x => x.OmitAutoProperties());
// this is valid
var configuredFixture = fixture.Customize(new AutoMoqCustomization());

我问是因为我曾想过使用流畅的样式来内联自定义,执行如下操作,这当然是无效的。

var localFixture = fixture
    .Customize(new AutoMoqCustomization())
    .Customize<whatever>(x => x.OmitAutoProperties()));

同时提供特定函数的通用和非通用版本是很常见的。当编译器可以明确地推断出泛型参数时,不需要为 Customize<T> 函数提供类型参数。

我不能说开发人员的意图,但我可以说图书馆如何提供两种不同的交互方式。

一种方法是通过流畅的界面。在流畅的界面中,方法几乎总是 return 对传递给它的对象实例的引用(并且它可能已经发生变异)。这是您概述的第一种方法,var localFixture = fixture.Customize(new AutoMoqCustomization());

另一种方法更像是功能接口。在功能范例中,副作用是一个很大的禁忌。换句话说,return 为当前日期的函数也不应该改变或修改它外部的任何其他内容。通过将 void 指定为另一个 Customize 方法的 return 类型,库的作者明确表示该函数的作用是改变 fixture 对象实例。

对库的文档 and/or 源进行更彻底的检查可以让您逐步了解这两种方法,以发现更多关于为什么按原样编写的信息。

总体答案是:因为我犯了错误

不幸的是,这两种方法并没有特别的关联,您应该真正认为它们是不同的,并且有两个不同的名称,例如 Foo<T>Bar.

当我写那些函数的时候,我想不出一个更好的名字;因此不幸的是,但主要是偶然的相似性。

IIRC,我在 AutoFixture 开发的不同阶段创建了这两种方法。 AFAIR,Customize<T> 排在第一位。

在使用了一些 AutoFixture 之后,我意识到使用正式的 'module' 或 'package' AutoFixture 系统会很好,所以我添加了 ICustomization,并且 Customize 方法。

我的初衷是可以将对 Customize 的调用链接在一起,所以我添加了 Fluent Interface (i.e. returned the IFixture instance) to enable that. The intent was to make it a convenience, but in hindsight, I consider it a mistake. The method does mutate the input argument, so that design violates Command Query Separation.

不过,在我看来,Fluent Interfaces 在当时风靡一时...

确实应该将 an issue 添加到 AutoFixture 存储库以从 Customize...

中删除 return 值