C# 将for循环转换为具有索引的foreach

C# 将for循环转换为具有索引的foreach,c#,for-loop,foreach,tostring,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++) {

我有一个
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();
 } 
public重写字符串ToString()
{
StringBuilder输出=新的StringBuilder();
AppendFormat(“{0}”,count);
对于(var指数=0;指数
以下是基于当前代码的重构

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,您可以对索引的
选择执行相同的操作,而无需直接调用引擎盖下使用的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();
} 

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

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();
}
public override string ToString()
{
    return count.ToString()
        + String.Join(" ",
            array.Select((x, n) => $"{x}{x.GetInfo}{String.Join(" ", x.Content(n))}"));
}
在任何情况下,您都将使用
int索引。根据
性能
的变化将其移动到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(
        string.Concat(
            item, 
            item.GetInfo(), 
            string.Join("", item.Content(index))
            )));
    return output.ToString();
}

无论如何,在性能方面,As
string.Concat
会更受欢迎。如果需要格式化,请选择其他格式。

根据
total
count
的不同,您可以重构为如下内容:

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();
}
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++);
        }
    }
}
公共静态类Ex
{
公共静态IEnumerable选择(此IEnumerable源,Func投影)
{
int指数=0;
foreach(源中的var项)
{
收益率回报预测(项目,指数+);
}
}
}

为什么投反对票,因为这太广泛了?好吧,为什么投反对票?这怎么会太宽了?A在这里很有用。谢谢你的回答。如果我不想浏览
array
的所有内容,因为其中一些内容是空的,该怎么办。是否可以对每个项目进行筛选,以仅获取非
null
的项目。ie
array.Where(item=>item!=null)
ok然后在foreach中进行检查,您可以中断或继续。这也行,但我必须接受第一个,很好。谢谢。LINQ不是我的选择。对不起,问题一开始没有说明。@hello-我给了你一个非LINQ的解决方案。