我有两种扩展方法:
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类型时才选择第二个重载。有两种方法可以在两种情况下选择第二次重载吗?
答案 0 :(得分:7)
第一个重载是更好的匹配,因为T被推断为List<Customer>
,这给出了完全匹配。对于第二个重载,它会将T推断为Customer
,因此参数将为IEnumerable<Customer>
,这与List<Customer>
不完全匹配。
答案 1 :(得分:5)
不要这么认为。不要认为在这个案例IEnumerable<T>
重载总是会被调用,因为它与T
类型的较少准确匹配。如果您没有指定具体的IEnumerable<T>
,那么最佳匹配将始终是第一种方法,在此情况下。
答案 2 :(得分:1)
ShouldHave()具有双重含义。在第一种情况下,ShouldHave()有一个关于subject-parameter提供的对象的返回。在第二种情况下,返回是关于枚举中的项目,而不是关于枚举本身。
如果我创建自己的集合并且我想测试这个集合本身(而不是项目),我当然希望调用ShouldHave(这个T主题)而不是ShouldHave(这个IEnumerable主题)。
也许你应该重新考虑你的设计。 第二个ShouldHave()做两件事,所以应该分成一个方法来提取集合项和调用你已经拥有的第一个ShouldHave()。
答案 3 :(得分:1)
在Fluent Assertion 2.0中,我终于设法以一种体面的方式解决了上述问题。在这里阅读所有相关内容: http://www.dennisdoomen.net/2012/09/asserting-object-graph-equivalence.html