Примерно так должно работать:
ArrayList1.AddRange(dtGetImages.Rows.Cast(Of DataRow)().[Select](Function(r) r(0).ToString()).ToArray())
Обновление
Здесь работает несколько концепций. Прежде всего, вы не пытаетесь добавить строк в список, а, скорее, первое значение в каждой строке. Как вы упомянули, вы можете использовать цикл for
, чтобы вывести это значение из каждой строки и добавить его в список, но подобные циклы не являются очень краткими или декларативными. Вот почему у нас есть LINQ (Language-Integrated Queries): платформа, которая упрощает преобразование коллекций значений.
Метод Select
- это метод расширения, определенный в инфраструктуре LINQ. В качестве аргумента она принимает функцию, определяющую, какое преобразование выполнять для каждого элемента в данной коллекции. Когда вызывается результат Select
, данная функция выполняется для каждого значения, создавая новую коллекцию на основе результатов. Здесь мы даем ему функцию:
Function(r) r(0).ToString()
..., что говорит об этом:
Учитывая переменную r
, получить нулевой индекс r
и вызвать ToString()
для результата.
Таким образом, если этот Select
метод вызывается для IEnumerable<DataRow>
, результирующая коллекция будет IEnumerable<string>
. Так как метод ArrayList.AddRange
требует ICollection
, мы должны изменить наш IEnumerable<string>
на что-то, что реализует ICollection
. Как оказалось, массивы реализуют ICollection
, поэтому мы можем использовать метод ToArray()
из LINQ для преобразования его в значение, которое ArrayList.AddRange
примет.
Есть только одна проблема: класс DataTable был написан до того, как дженерики были частью платформы .NET, поэтому класс DataRowCollection
реализует неуниверсальный интерфейс IEnumerable
, а не строго типизированный IEnumerable<DataRow>
. Поскольку наш метод Select
должен начинаться с IEnumerable<DataRow>
, нам нужно что-то сделать, чтобы преобразовать dtGetImages.Rows
в IEnumerable<DataRow>
. Метод Cast
, также предоставленный LINQ, сделает это для нас. Мы сообщаем Cast
, что мы знаем, что все в данном IEnumerable
(в данном случае DataRowCollection
) будет DataRow
, так что он может безопасно преобразовать каждый элемент в DataRow
, оставляя нам с IEnumerable<DataRow>
, что нам нужно использовать метод Select
.
Надеюсь, это все хорошо объясняет. Вы должны знать, что это не исключает использование циклов. Когда вы вызываете .ToArray()
, он извлекает элементы из .Select
, который извлекает элементы из .Cast
, который перебирает dtGetImages.Rows
так же, как если бы вы написали цикл for
для заполнения массива. Разница лишь в том, что LINQ делает ваш код более декларативным. Это разница между словами:
Для каждого DataRow в свойстве Rows этого DataTable я собираюсь создать переменную с именем row
. Затем я вызову ToString
для нулевого элемента этой переменной и добавлю результат в ArrayList.
... и говорят:
Я звоню ToString
на нулевой элемент каждого DataRow в свойстве Rows этого DataTable и добавляю результаты в ArrayList.
Они оба означают примерно одно и то же, но каждый из них яснее и лаконичнее.