在阵列上使用IEnumerable有什么好处?

MX *_*X D 4 c# linq performance

Code Review.stackexchange上询问我的问题之后,我被建议使用以下代码片段.我注意到在传输过程中string [] Lines被设置为IEnumerable.

在查看IEnumerable函数之后,我没有找到任何暗示任何性能改进的东西.那么这只是为了可读性吗?或者使用IEnumerable而不是数组实际上存在性能差异或一般优势?

private void ProcessSingleItem(String fileName, String oldId, String newId)
{
    string[] lines = File.ReadAllLines(fileName);

    File.WriteAllText(fileName, ProcessLines(lines, oldId, newId));
}  

private String ProcessLines(IEnumerable<String> lines, String oldId, String newId)
{
    StringBuilder sb = new StringBuilder(2048);
    foreach (String line in lines)
    {
        sb.AppendLine(line.Replace(oldId, newId));
    }
    return sb.ToString();
}  
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 13

到目前为止,所有答案都表示,在您接受的内容中更为通用会使您的辅助方法更有用.这是对的.但是,还有其他考虑因素.

  • Pro:采用序列而不是数组与正在调用代码的开发人员进行通信"我不会改变你传递给我的对象".当我调用一个接受数组的方法时,我怎么知道它不会改变数组呢?

  • Con:采用更通用的类型意味着您的方法必须对于更通用类型的任何实例都是正确的.你怎么知道这是对的?测试.因此,采用更通用的类型可能意味着更大的测试负担.如果您采用数组,那么您只有几种情况:空数组,空数组,协变数组等.如果您采用序列,则要测试的案例数量会更大.

  • 你提到了表现.请记住,根据感受而不是经验数据做出微观决策是获得良好表现的可怕方法.相反,设定一个绩效目标,根据该目标衡量进度,并使用分析器找到最慢的东西; 首先攻击.甲foreach阵列上循环编译成等效for回路; 上的IEnumerable代码是更加复杂和可能的几个微秒更慢.您的应用程序在市场中的成功或失败是由这些微秒决定的吗?如果是这样,那么仔细测量性能.如果没有,请按照您喜欢的方式编写代码,如果您引入了导致您不再符合目标的回归,则自动化测试会告诉您相关信息.您正在运行自动化性能测试,对吧?如果你非常关心表现,你应该是.

  • @ColeCampbell:在数组的情况下导致分配的原因是什么?允许编译器在数组上实现`foreach`,因为它是一个`for`循环,而Microsoft C#编译器也这样做.Unity使用的编译器不这样做吗? (2认同)

C.E*_*uis 12

数组一个实现IEnumerable.

lines方法中的参数中使用的唯一成员是在中定义的成员IEnumerable.因此,您可以选择IEnumerable作为参数类型,并且在您接受的内容中最不挑剔,允许任何IEnumerable实现作为参数提供.

考虑这个例子:

ProcessLines(GetItems(), ...);

public IEnumerable<string> GetItems()
{
    yield return "ItemAlwaysGetsIncluded";

    if (!once_in_blue_moon)
    {
        yield break;
    }

    yield return "ItemIncludedOnceInABlueMoon";
}
Run Code Online (Sandbox Code Playgroud)

很难说出性能影响是什么,因为IEnumerable几乎可以说是什么.