Как мне ограничить цикл foreach n запусками?

#c# #datatable

#c# #datatable

Вопрос:

Предполагая, что у меня есть следующий цикл:

 foreach (DataRow dr in table.rows)
{
    ...
}
  

Как мне не допустить, чтобы он выполнялся чаще, чем n раз?

Комментарии:

1. Для начинающего программиста обязательно ознакомьтесь с ответами, в которых в циклах используются явные счетчики, даже если вы в конечном итоге выберете один из Take(50) подходов.

2. @AnthonyPegram: Очень хорошее предложение для тех, кто учится.

Ответ №1:

В случае rows , если на самом деле это просто from DataTable.Rows , приведенные простые Take ответы не будут работать, поскольку DataRowCollection реализует только не универсальный IEnumerable интерфейс, тогда как LINQ нуждается в универсальном интерфейсе. Вам понадобится что-то вроде:

 // Uses DataTableExtensions.AsEnumerable
foreach (DataRow dr in table.AsEnumerable().Take(50))
  

или

 // Uses Enumerable.Cast
foreach (DataRow dr in rows.Cast<DataRow>().Take(50))
  

Комментарии:

1. Вы заставили меня сомневаться в исправлении опечаток 😉 Был ли знак плюс в конце второго примера преднамеренным?

2. @JamesJohnson: Нет, на этот раз просто опечатка 🙂

Ответ №2:

Вы могли бы попробовать

 using System.Linq;
...
...
...
foreach (DataRow dr in rows.Cast<DataRow>().Take(50)) { }
  

Обратите Cast<DataRow>() внимание, что для преобразования в необходимо выполнить вызов DataRowCollection IEnumerable<DataRow> , что позволит вам использовать метод Take() расширения.

Комментарии:

1. Вы пробовали этот код? Нет Take метода, доступного напрямую для DataRowCollection .

Ответ №3:

Вариант 1: иметь работающий счетчик:

 var i = 0;
foreach (DataRow dr in rows)
{
    i  ;
    if(i >= 50) break;
}
  

Вариант 2: используйте цикл for

 for(int i = 0; i <= 50; i  ) {
    // This might actually crash if there are fewer than 50 rows
    var row = rows[i]; 
}
  

Ответ №4:

В идеале измените исходный запрос, чтобы возвращать только 50 строк. Нет смысла извлекать больше, чем вы хотите использовать.

Другие предоставили хорошие альтернативы, если это не вариант.

Ответ №5:

Попробуйте это:

 foreach (DataRow dr in table.Rows.Cast<DataRow>().Take(50))
{
    //your logic
}
  

Ответ №6:

Подходы .Cast<DataRow>().Take(50) Linq хороши, но это действительно простая проблема для for цикла:

 for( int i = 0; i < Math.Min(50, rows.Count);   i ) 
{ 
    var row = rows[i];
}