我想知道为什么泛型Customize
重载返回void
并且似乎在非泛型重载时改变了fixture,它采用{{1}的实例},返回ICustomization
?
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());
答案 0 :(得分:3)
总的答案是:因为我犯了错误
遗憾的是,这两种方法并不是特别相关,您应该将它们视为不同,并且有两个不同的名称,例如Foo<T>
和Bar
。
当我写这些功能时,我想不出更好的名字;因此,不幸的,但大多是偶然的,相似性。
IIRC,我在AutoFixture开发的不同阶段创建了这两种方法。 AFAIR,Customize<T>
排在第一位。
在使用AutoFixture之后,我意识到使用正式的'模块'或'包'系统进行AutoFixture很好,所以我添加了ICustomization
和Customize
方法去了用它。
我最初的意图是可以将对Customize
的调用链接在一起,因此我添加了Fluent Interface(即返回IFixture
实例)以启用它。目的是为了方便,但事后看来,我认为这是一个错误。方法 改变了输入参数,因此设计违反了Command Query Separation。
在我的辩护中,Fluent Interfaces当时风靡一时......
真的应该将an issue添加到AutoFixture存储库以从Customize
中删除返回值...
答案 1 :(得分:0)
提供特定功能的通用版本和非通用版本非常常见。当编译器可以明确地推断出泛型参数时,不需要提供Customize<T>
函数的类型参数。
我无法与开发人员的意图交谈,但我可以谈谈图书馆如何提供两种不同风格的互动。
一种方法是通过流畅的界面。在一个流畅的接口中,方法几乎总是返回对传递给它的对象实例的引用(以及它可能已经变异)。这是您概述的第一种方法var localFixture = fixture.Customize(new AutoMoqCustomization());
另一种方法更多的是功能界面。在一个功能范例中,副作用是一个很大的禁忌。换句话说,返回当前日期的函数也不应该改变或修改其外部的任何其他内容。通过将void
指定为另一个Customize
方法的返回类型,库的作者明确表示该函数的作用是改变fixture
对象实例。
对图书馆的文档和/或来源进行更彻底的检查,可以让您通过这两种方法来了解更多关于它的原因。