【问题标题】:How can I loop through a List<T> and grab each item?如何遍历 List<T> 并获取每个项目?
【发布时间】:2013-09-22 16:17:42
【问题描述】:

如何循环遍历列表并获取每个项目?

我希望输出如下所示:

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; }
}

【问题讨论】:

    标签: c# for-loop collections


    【解决方案1】:

    foreach:

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

    MSDN Link

    另外,因为它是一个List&lt;T&gt;.. 实现了一个索引器方法[],你也可以使用一个普通的for 循环......虽然它的可读性较差(IMO):

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

    【讨论】:

    • @awudoin 什么?不,它没有......它在堆栈上创建一个引用......除此之外,它没有。 foreach 不会克隆对象..
    • 我应该澄清一下:它还创建了一个Enumerator.. 这是一个struct.. 它也在堆栈上。所以我还是不太明白你的评论是什么意思。
    • 你是对的......它只是一个Enumerator,而不是对象的副本。但事实仍然存在,这取决于您在做什么,foreach 循环与for 循环相比会产生更多开销。我刚刚对您的代码进行了快速测试,在 List 中有 100,000 个条目,foreach 循环花费了两倍的时间(实际上是 1.9 倍)。这不一定在所有情况下都是正确的,但在许多情况下都是如此。这取决于列表的大小、您在循环中执行的操作数等......这就是我的意思。
    【解决方案2】:

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

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

    【讨论】:

    • 这样干净多了
    • @jet_choong 这是个人意见。我的是它并不比 foreachfor 更清楚。
    【解决方案3】:

    就像任何其他系列一样。添加了List&lt;T&gt;.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));
    

    【讨论】:

    • 另一个警告,如果你有一个大列表,(我的意思是超过 100,000 个项目)myMoney.Count 开始需要一段时间,因为它必须遍历列表来执行计数,并且在上面的示例中,每次循环都会计算 myMoney.Count。所以使用 int myMoneyC=myMoney.Count; for(int i=0;i
    • @SuperGSJ 你测试过这个吗?我希望它在您编译发布时得到优化。
    【解决方案4】:

    这就是我将使用更多functional way 编写的方式。代码如下:

    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}");
    });
    

    【讨论】:

    • 谢谢。这是完成此任务的非常短的方法。您还使用了 VS 2017/.NET 4.7 中引入的 writeLine 新的紧凑语法。
    【解决方案5】:

    低级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);
        }
    }
    

    【讨论】:

    • 需要注意的是,如果List发生变化,会得到“Collection was modified; enumeration operation may not execute”。用这个方法。
    • @NorbertBoros 不仅是这个方法,而且任何枚举列表的方法(例如foreach)和列表发生变化,都会抛出相同的异常。 for 循环不会枚举列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多