12

我有两种扩展方法:

public static IPropertyAssertions<T> ShouldHave<T>(this T subject)
{
    return new PropertyAssertions<T>(subject);
}

public static IPropertyAssertions<T> ShouldHave<T>(this IEnumerable<T> subject)
{
    return new CollectionPropertyAssertions<T>(subject);
}

现在我编写了一些使用它的代码:

List<Customer> collection2 = new List<Customer>(); 
collection2.ShouldHave(); //first overload is chosen
IEnumerable<Customer> collection3 = new List<Customer>(); 
collection3.ShouldHave(); //second overload is chosen

仅当我明确指定 IEnumerable 类型时才选择第二个重载。有没有办法在两种情况下都选择第二个重载?

4

4 回答 4

7

第一个重载是更好的匹配,因为 T 被推断为List<Customer>,这给出了精确匹配。对于第二个重载,它会将 T 推断为Customer,因此参数将是IEnumerable<Customer>,与 相比,它的匹配不太精确List<Customer>

于 2012-03-25T14:15:45.303 回答
5

不要这么想。不要认为在这种情况下IEnumerable<T>总是会调用重载,因为它在类型方面的匹配不太T准确。如果你不指定具体IEnumerable<T>的,最好的匹配将始终是第一个方法,在这种情况下。

于 2012-03-25T12:43:32.787 回答
1

ShouldHave() 有双重含义。在第一种情况下,ShouldHave() 有一个关于主题参数提供的对象的返回值。在第二种情况下,返回是关于枚举中的项目,而不是关于枚举本身。

如果我创建自己的集合并且我想测试这个集合本身(而不是项目),我当然希望调用 ShouldHave(this T subject) 而不是 ShouldHave(this IEnumerable subject)。

也许你应该重新考虑你的设计。第二个ShouldHave() 做了两件事,所以应该分成一个提取集合项的方法和一个对你已经拥有的第一个ShouldHave() 的调用。

于 2012-03-25T16:12:33.453 回答
1

在 Fluent Assertion 2.0 中,我终于设法以一种体面的方式解决了上述问题。在这里阅读所有相关信息:http: //www.dennisdoomen.net/2012/09/asserting-object-graph-equivalence.html

于 2012-09-05T18:33:58.660 回答