如何循环遍历List<T>并获取每个项?

235

我如何遍历一个列表并获取每个项目?

我希望输出的结果是这样的:

Console.WriteLine("amount is {0}, and type is {1}", myMoney.amount, myMoney.type);

这是我的代码:

static void Main(string[] args)
{
    List<Money> myMoney = new List<Money> 
    {
        new Money{amount = 10, type = "US"},
        new Money{amount = 20, type = "US"}
    };
}

class Money
{
    public int amount { get; set; }
    public string type { get; set; }
}
6个回答

355

foreach循环:

foreach (var money in myMoney) {
    Console.WriteLine("Amount is {0} and type is {1}", money.amount, money.type);
}

MSDN链接

另外,由于它是一个实现了索引器方法[]List<T>,因此您也可以使用普通的for循环.. 尽管这样不太易读(在我看来):

for (var i = 0; i < myMoney.Count; i++) {
    Console.WriteLine("Amount is {0} and type is {1}", myMoney[i].amount, myMoney[i].type);
}

7
@awudoin 什么?不,它并不会在堆栈上创建一个引用。除此之外,它没有任何其他作用。foreach 循环并不会克隆对象。 - Simon Whitehead
2
我应该澄清一下:它还创建了一个Enumerator..它是一个struct..也在堆栈上。所以我仍然不太明白你在评论中的意思。 - Simon Whitehead
8
你是正确的,这只是一个“枚举器”而不是对象的副本。但事实仍然存在,根据你所做的操作,使用“foreach”循环会比使用“for”循环有更多的开销。我刚刚用你的代码在包含100,000个项的“List”上进行了快速测试,结果“foreach”循环所需时间是“for”循环的两倍长(实际上是1.9倍长)。这并不一定在所有情况下都成立,但在许多情况下是如此。这取决于列表的大小,循环内执行的操作数量等等...这就是我的意思。 - awudoin

42

为了完整起见,还有一种LINQ/Lambda的方式:

myMoney.ForEach((theMoney) => Console.WriteLine("amount is {0}, and type is {1}", theMoney.amount, theMoney.type));

这样更加简洁。 - jet_choong
1
@jet_choong 这只是个人观点。我的看法是它既不比 foreach 更清晰,也不比 for 更清晰。 - Maarten
取决于其中的代码长度,我猜... - Unterbelichtet
取决于其中的代码长度,我猜... - undefined

25

就像其他任何集合一样。加上了 List<T>.ForEach 方法。

foreach (var item in myMoney)
    Console.WriteLine("amount is {0}, and type is {1}", item.amount, item.type);

for (int i = 0; i < myMoney.Count; i++)
    Console.WriteLine("amount is {0}, and type is {1}", myMoney[i].amount, myMoney[i].type);

myMoney.ForEach(item => Console.WriteLine("amount is {0}, and type is {1}", item.amount, item.type));

7
再次提醒,如果你的列表很大(我指的是超过 100,000 项),myMoney.Count 开始变得很慢,因为它必须遍历列表执行 Count 操作。在上面的 for 循环示例中,每次循环都会计算 myMoney.Count。因此,使用 int myMoneyC=myMoney.Count; for(int i=0;i < myMoneyC; i++) 可以使这个循环快很多。 - SuperGSJ
@SuperGSJ 你测试过这个吗?我认为在编译发布版本时会进行优化。 - Maarten

16

这是我使用更多函数式编程的写法。下面是代码:

new List<Money>()
{
     new Money() { Amount = 10, Type = "US"},
     new Money() { Amount = 20, Type = "US"}
}
.ForEach(money =>
{
    Console.WriteLine($"amount is {money.Amount}, and type is {money.Type}");
});

2
谢谢。这是实现此任务的非常简短的方法。您还使用了在VS 2017 / .NET 4.7中引入的新的紧凑语法writeLine。 - Deep

3
低级的iterator操纵代码:
List<Money> myMoney = new List<Money>
{
    new Money{amount = 10, type = "US"},
    new Money{amount = 20, type = "US"}
};
using (var enumerator = myMoney.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
        var element = enumerator.Current;
        Console.WriteLine(element.amount);
    }
}

需要注意的是,如果更改了列表,使用此方法将会出现“集合已修改;可能无法执行枚举操作”的错误。 - Mecanik
2
@NorbertBoros 不仅是这个方法,任何枚举列表的方法(例如foreach),如果列表发生更改,都会抛出相同的异常。for循环不会枚举列表。 - Maarten

0

你也可以使用 while 循环来完成它

   int ctr = 0;
   while (ctr <= myMoney.Count - 1)
   {
       var data = myMoney[ctr];
       Console.WriteLine($"{data.amount} - {data.type}");
       ctr++;
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接