Як я можу переглядати список <T> та захоплювати кожен елемент?


176

Як я можу переглядати список та перехопити кожен елемент?

Я хочу, щоб результат виглядав так:

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

Відповіді:


274

foreach:

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

MSDN Посилання

Крім того, оскільки це List<T>.., який реалізує метод індексатора [], ви також можете використовувати звичайний 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);
}

7
@awudoin Що? Ні, це не так ... це створює посилання на стек .. крім цього, це не так. A foreachне клонує об’єктів ..
Саймон Уайтхед

2
Я повинен уточнити: він також створює Enumerator.. який є struct.., який також є на стеці. Тому я все ще не дуже розумію те, що ви отримали зі своїм коментарем.
Саймон Уайтхед

7
Ви маєте рацію .... це просто Enumeratorкопія об'єкта, а не його копія. Але факт залишається фактом, залежно від того, що ви робите, є більше накладних витрат із foreachциклом проти forциклу. Я щойно провів швидкий тест з вашим кодом зі 100 000 записів у, Listа foreachцикл зайняв удвічі довше (насправді в 1,9 рази довше). Це не обов'язково вірно у всіх ситуаціях, але у багатьох. Це залежить від розміру списку, кількості операцій, які ви робите в циклі тощо. Це було те, що я отримував.
awudoin

36

Для повноти існує також спосіб LINQ / Lambda:

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

20

Як і будь-яка інша колекція. З доповненням 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));

6
Ще одне слово попередження, якщо у вас великий список (маючи на увазі понад 100 000 предметів), myMoney.Count починає тривати деякий час, як це потрібно для проходження списку для виконання підрахунку, і в прикладах вище myMoney. Кількість підраховується кожного разу навколо циклу. Отже, використовуючи int myMoneyC = myMoney.Count; for (int i = 0; i <myMoneyC; i ++) зробить цю петлю в багато разів швидшою.
SuperGSJ

12

Ось як я писав би, використовуючи більше 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}");
});

2
Дякую. Це дуже короткий шлях для досягнення цього завдання. Ви також використали новий і компактний синтаксис writeLine, який був представлений у VS 2017 / .NET 4.7.
Deep
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.