使用索引将for循环转换为foreach

时间:2016-09-26 00:09:45

标签: c# for-loop foreach tostring

我有这个ToString方法来写出对象。我试图将for循环转换为foreach循环。 不使用LINQ。

任何指针都将受到赞赏。

 public override string ToString()
 {
     StringBuilder output = new StringBuilder();
     output.AppendFormat("{0}", count);
     for (var index = 0; index < total; index++)
     {
         output.AppendFormat("{0}{1}{2} ", array[index], array[index].GetInfo,
                              string.Join(" ", array[index].Content(index)),
                            );
     }
     return output.ToString();
 } 

3 个答案:

答案 0 :(得分:3)

以下是基于您当前代码的重构。

public override string ToString() {
    var output = new StringBuilder();
    output.AppendFormat("{0}", count);
    var index = 0;
    foreach (var item in array) {
        if (item!=null) {
            output.AppendFormat("{0}{1}{2} ", item, item.GetInfo,
                              string.Join(" ", item.Content(index++)),
                            );
        }
    }
    return output.ToString();
} 

使用linq,您可以使用索引Select执行相同操作,而无需直接调用引擎盖下使用的foreach

public override string ToString() {
    var output = new StringBuilder();
    output.AppendFormat("{0}", count);
    array.Select((item, index) =>
        output.AppendFormat("{0}{1}{2} ", item, item.GetInfo,
                              string.Join(" ", item.Content(index)),
                            )
    );
    return output.ToString();
} 

答案 1 :(得分:2)

从技术上讲,你可以这样做:

public override string ToString()
{
    StringBuilder output = new StringBuilder();
    output.Append(count);

    int index = 0;
    foreach (var item in array)
    {           
        output.Append($"{item}{item.GetInfo()}{string.Join(" ", item.Content(index))}");
        index++;
    }
    return output.ToString();
}

无论如何,无论如何,你都会去int index。按照performance的说法,将它移到foreach上并没有那么多的帮助。

如果您真的不想在任何地方编写递增索引,也可以尝试自己的ForEach扩展。

public static class EnumerableExtensions
{
    public static void ForEachWithIndex<T>(this IEnumerable<T> sequence, Action<int, T> action)
    {
        // argument null checking omitted
        int i = 0;
        foreach (T item in sequence)
        {
            action(i, item);
            i++;
        }
    }
}

然后您的方法会更简单,但您还需要管理一个课程:

public override string ToString()
{
    StringBuilder output = new StringBuilder();
    output.Append(count);
    array.ForEachWithIndex((index, item) => output.Append($"{item}{item.GetInfo()}{string.Join("", item.Content(index))}"));
    return output.ToString();
}

为了便于阅读,如果你真的只是并排放置字符串:

public override string ToString()
{
    StringBuilder output = new StringBuilder();
    output.Append(count);
    array.ForEachWithIndex((index, item) => output.Append(
        string.Concat(
            item, 
            item.GetInfo(), 
            string.Join("", item.Content(index))
            )));
    return output.ToString();
}

无论如何,string.Concat会更受赞赏。如果您需要格式化,请选择其他人。

答案 2 :(得分:2)

根据totalcount的不同,您可以重构这样的内容:

public override string ToString()
{
    return count.ToString()
        + String.Join(" ",
            array.Select((x, n) => $"{x}{x.GetInfo}{String.Join(" ", x.Content(n))}"));
}

String.Join通常可以比StringBuilder表现得更好,所以这不是一个糟糕的选择。

你去吧。此扩展程序不需要LINQ:

public static class Ex
{
    public static IEnumerable<R> Select<T, R>(this IEnumerable<T> source, Func<T, int, R> projection)
    {
        int index = 0;
        foreach (var item in source)
        {
            yield return projection(item, index++);
        }
    }
}