为什么将List <term>的参数重构为IEnumerable <term>?</term> </term>

时间:2011-12-13 12:38:01

标签: c# interface refactoring resharper

我有一个看起来像这样的方法:

    public void UpdateTermInfo(List<Term> termInfoList)
    {
        foreach (Term termInfo in termInfoList)
        {
            UpdateTermInfo(termInfo);
        }
        m_xdoc.Save(FileName.FullName);
    }

Resharper建议我将方法签名更改为IEnumerable<Term>而不是List<Term>。这样做有什么好处?

5 个答案:

答案 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,因为它们都实现了该接口。