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();
}
无论如何,在性能方面,Asstring.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
的项目。iearray.Where(item=>item!=null)
ok然后在foreach中进行检查,您可以中断或继续。这也行,但我必须接受第一个,很好。谢谢。LINQ不是我的选择。对不起,问题一开始没有说明。@hello-我给了你一个非LINQ的解决方案。