为什么要重构ListIEnumerable< Term>

本文关键字:Term IEnumerable List 重构 为什么 | 更新日期: 2023-09-27 18:17:47

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

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

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

为什么要重构List<Term>IEnumerable< Term>

另一个答案指出,通过选择"较大"的类型,您可以允许更多的调用者调用您。这本身就是做出这种改变的充分理由。然而,还有其他原因。我建议你做这个改变,因为当我看到一个方法接受一个列表或数组时,我想的第一件事是"如果这个方法试图改变列表/数组中的一个项目怎么办?"

您想要桶的内容,但您不仅需要桶,还需要更改其内容的能力。如果你不打算使用这种能力,为什么要要求它呢?当你说"这个方法不能取任何旧序列;它必须接受一个以整数为索引的可变列表"我认为你在调用者上做了这个要求,因为你要利用的功能。

如果"我打算搞乱你的数据结构"不是你打算传达给方法调用者的,那么就不要传达它。一个接受序列的方法传达了"我要做的最多就是按顺序从这个序列中读取"。

简单地说,接受一个可枚举对象可以让你的函数兼容更大范围的输入参数,比如数组和LINQ查询。

要详细说明如何接受LINQ查询,可以这样做:

UpdateTermInfo(myTermList.Where(x => somefilter));

另外,指定一个接口而不是一个具体的类允许其他人提供他们自己的接口实现。通过这种方式,你是"订阅"而不是"禁止"。(是的,我刚造了一个词。)

一般情况下(除了许多与您希望为以后可能的修改保留哪些类型的功能有关的例外),使用尽可能通用的参数实现函数是最佳实践。这为函数的使用者提供了最大的灵活性。

因此,如果您对该函数使用列表毫无兴趣(可能是因为在以后的某个日期您可能希望使用Count或索引操作符等属性),我强烈建议您考虑使用IList<Term>而不是List<Term>,原因如上所述。

List实现了IEnumerable,使用它会使事情更灵活。如果一个实例出现了,你不想使用List,而想使用一个不同的集合对象,它可以很容易地从IEnumerable强制转换。

例如,IEnumerable允许你使用Arrays和许多其他的,而不是总是使用List

Inumerable只是一个项目的集合,不同于List,在那里你可以添加,删除,排序,使用For Each, Count等

该重构背后的主要思想是使方法更通用。你不说你想要什么样的数据结构,只说你需要它:你可以遍历它的元素。

所以后来,当你觉得O(n)搜索对你来说不够好时,你只需要改变一行,然后继续。

如果你使用List,那么你就限制了自己只能使用List的具体实现,而使用IEnumerable你可以传入数组、列表、集合,因为它们都实现了那个接口。