我有一个看起来像这样的方法:
public void UpdateTermInfo(List<Term> termInfoList)
{
foreach (Term termInfo in termInfoList)
{
UpdateTermInfo(termInfo);
}
m_xdoc.Save(FileName.FullName);
}
Resharper建议我将方法签名更改为IEnumerable<Term>
而不是List<Term>
。这样做有什么好处?
答案 0 :(得分:17)
其他答案指出,通过选择“更大”类型,您可以允许更广泛的来电者给您打电话。这本身就足以说明这一变化。但是,还有其他原因。我建议您进行此更改,因为当我看到一个采用列表或数组的方法时,我认为首先是“如果该方法尝试更改列表/数组中的项目会怎么样?”
您想要存储桶的内容,但您不仅需要存储桶,还需要更改其内容的功能。如果你不打算使用那种能力,你为什么要这样做?当你说“这个方法不能采用任何旧的序列;它必须采用一个由整数索引的可变列表”我认为你在调用者上提出了这个要求,因为你'重新利用这种力量。
如果“我打算弄乱你的数据结构”并不是你打算与方法的调用者进行通信,那么就不要那样做了。采用序列的方法传达“我将要做的最多的事情是按顺序从这个序列中读取”。
答案 1 :(得分:6)
简而言之,接受枚举允许您的函数与更广泛的输入参数范围兼容,例如数组和LINQ查询。
要阐述接受LINQ查询,可以这样做:
UpdateTermInfo(myTermList.Where(x => somefilter));
此外,指定接口而不是具体类允许其他人提供他们自己的接口实现。通过这种方式,您是“订阅”而非“禁止”。 (是的,我刚刚说了一句话。)
一般而言(有许多例外情况与您希望为以后的修改保留哪种能力有关),最佳实践是使用最常见的参数来实现函数。这为您的功能消费者提供了最大的灵活性。
因此,如果您使用此函数的列表(可能是因为在某些日期您可能希望使用Count
或索引运算符等属性),我会强烈建议您考虑使用IList<Term>
代替List<Term>
,原因如上所述。
答案 2 :(得分:3)
List
实现IEnumerable
,使用它可以使事情变得更加灵活。如果有一个实例出现在你不想使用List
并且想要使用不同的集合对象的情况下,它会轻易地从IEnumerable
投射。
例如IEnumerable
允许您使用Arrays
和其他许多人,而不是始终使用List
。
Inumerable
只是一个项目集合,与List
不同,您可以在其中添加,删除,排序,使用For Each,Count等。
答案 3 :(得分:0)
重构背后的主要思想是你使方法更通用。您没有说出您想要的数据结构,只需要您需要的数据结构:您可以遍历其元素。
所以稍后,当你确定O(n)搜索对你来说不够好时,你只需改变一行并继续前进。
答案 4 :(得分:0)
如果您使用List,那么您只能使用List的具体实现,与IEnumerable一样,您可以传入Arrays,Lists,Collections,因为它们都实现了该接口。