可以用LINQ语句替换所有'for'循环吗?

Awk*_*der 19 c# linq for-loop

是否可以将以下'foreach'编写为LINQ语句,我想更普遍的问题可以将任何for循环替换为LINQ语句.

我对任何潜在的性能成本都不感兴趣,只是在传统的命令式代码中使用声明性方法的潜力.

    private static string SomeMethod()
    {
        if (ListOfResources .Count == 0)
            return string.Empty;

        var sb = new StringBuilder();
        foreach (var resource in ListOfResources )
        {
            if (sb.Length != 0)
                sb.Append(", ");

            sb.Append(resource.Id);
        }

        return sb.ToString();
    }
Run Code Online (Sandbox Code Playgroud)

干杯

AWC

Eri*_*ert 26

当然.哎呀,你可以用LINQ查询替换算术:

http://blogs.msdn.com/ericlippert/archive/2009/12/07/query-transformations-are-syntactic.aspx

但你不应该.

查询表达式的目的是表示查询操作."for"循环的目的是迭代特定语句,以便多次执行其副作用.这些往往是非常不同的.我鼓励更换循环,其目的仅仅是使用更高级别的结构查询数据,以便更清楚地查询数据.我强烈反对用查询理解替换产生副作用的代码,尽管这样做是可能的.

  • @Tom:没有副作用的操作应该能够(1)懒惰地评估,(2)与其他惰性操作无序评估,(3)评估一次并缓存,(4)如果缓存策略评估两次抛出缓存的结果.如果要向控制台写入内容,则希望以与所有其他写入相关的正确顺序写入ONCE. (4认同)
  • @Tom:我没跟你的想法.肯定写出一条线是副作用,不是吗? (3认同)

Jar*_*Par 15

总的来说是的,但是有些特殊情况非常困难.例如,一般情况下的以下代码在没有大量黑客攻击的情况下不会移植到LINQ表达式.

var list = new List<Func<int>>();
foreach ( var cur in (new int[] {1,2,3})) {
  list.Add(() => cur);
}
Run Code Online (Sandbox Code Playgroud)

原因在于,使用for循环,可以看到在闭包中如何捕获迭代变量的副作用.LINQ表达式隐藏迭代变量的生命周期语义,并防止您看到捕获它的值的副作用.

注意.上面的代码等同于以下LINQ表达式.

var list = Enumerable.Range(1,3).Select(x => () => x).ToList();
Run Code Online (Sandbox Code Playgroud)

foreach示例生成一个Func<int>对象列表,这些对象都返回3. LINQ版本生成一个列表,Func<int>其中分别返回1,2和3.这使得这种捕获方式难以移植.