Я пытаюсь заполнить DataTable.NET 4.5 из List<T>
, где T
- класс с свойством типа string
.
У меня есть функция makeNewDataTable()
которая создает экземпляр DataTable
и добавляет к нему набор столбцов; эта часть работает нормально.
Когда я вручную перебираю список, в DataTable добавляется правильное количество строк (с правильными данными):
DataTable dataTable = makeNewDataTable();
if (inputList != null)
{
//inputList.Select(item => dataTable.Rows.Add(item.Property, DBNull.Value));
foreach (var item in inputList)
{
dataTable.Rows.Add(item.Property, DBNull.Value);
}
}
Однако, если я попытаюсь использовать выражение лямбда в том же конце:
DataTable dataTable = makeNewDataTable();
if (inputList != null)
{
inputList.Select(item => dataTable.Rows.Add(item.Property, DBNull.Value));
//foreach (var item in inputList)
//{
// dataTable.Rows.Add(item.Property, DBNull.Value);
//}
}
то после, if
Заключительное выражение }
Я вижу, что dataTable.Rows.Count == 0
.
Почему я не вижу, как строки добавляются, когда я использую выражение лямбда, когда закодированный вручную цикл foreach работает нормально?
Бонусный вопрос: есть ли способ сделать то, что я хочу, используя более сжатый синтаксис лямбда-выражений, а не вручную кодировать цикл foreach?
Я не могу ответить на вопрос, почему, но я могу ответить на вопрос о бонусе: для этой цели вы должны использовать метод List.ForEach:
inputList.ForEach(item => dataTable.Rows.Add(item.Property, DBNull.Value));
Обратите внимание, что он доступен только для значения типа List
, а не для IList
или IEnumerable
, поэтому вам может потребоваться вызвать ToList()
.
Выбрать - итератор. Lambda определяет, как IEnumerable будет заполнен после начала перечисления. Но он начинается после использования foreach в результате выбора или принудительного перечисления с помощью ToList() или ToArray() или GetEnumerator(). MoveNext()... Это отложенное выполнение.
Не рекомендуется выполнять такие операции, как "Добавить в выборе". Поскольку он может выполняться параллельно по умолчанию, в будущих версиях.NET и Add могут быть небезопасными потоки
В "oldschool" нет ничего плохого в foreach, вы должны использовать lambdas, когда у вас есть причины: работать с деревьями выражений, захватывать контексты, быстро создавать анонимные методы в сценариях, когда вы вынуждены передавать делегат/выражение.
.Select()
сопоставляется из каждого элемента с вызовом функции, чтобы добавить строку вdataTable
который определен вне лямбда-выражения. Или, по крайней мере, это было то, что я думал, что это будет делать, но код явно не делает то, что я хотел. Полный оператор.Select()
здесь не возвращает ничего значимого.