Задать вопрос
YaKotikTvoy
@YaKotikTvoy
Стьюдик

Почему у меня под конец в листе rows начинают хранится одни и те же значения?

У меня есть таблица с тремя строками и четырьмя атрибутами, я хочу просто вывести данные в ListView, с помощью DataReader.
private List<string[]> rows = new List<string[]>();

private void QueryExecute(object sender, EventArgs e)
        {
            SqlCommand command = new SqlCommand(SelectQueryString.Text, MyDBConnection);

            SqlDataReader rd = null;
            try
            {
                rd = command.ExecuteReader();

                for (int i = 0; i < rd.FieldCount; i++)
                    SelectList.Columns.Add(rd.GetName(i));
                string[] row = new string[rd.FieldCount];

                while (rd.Read())
                {
                    for (int i = 0; i < rd.FieldCount; i++)
                        row[i] = Convert.ToString(rd[$"{rd.GetName(i)}"]);
                    rows.Add(row);
                }// После того как он выходит из цикла, все строки в rows становятся копиями последней, третьей строки. 
            }// И в ListView выходят абсолютно схожие записи, что, естественно, неверно.
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (rd != null && !rd.IsClosed)
                    rd.Close();
            }
            RefreshList(rows);
        }
        private void RefreshList(List<string[]> list)
        {
            SelectList.Items.Clear();
            foreach (string[] s in list)
                SelectList.Items.Add(new ListViewItem(s));
        }

Вот что выводит
62af48320e17b280583481.png
Как мне это исправить, как сделать, чтобы выводились именно те записи, которые в базе, а не клонированные записи в листе rows?
  • Вопрос задан
  • 48 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
@Miron11
Пишу sql 20 лет. Срок :)
Есть два подхода, чтобы справиться, перенести линию кода
string[] row = new string[rd.FieldCount];
сюда
while (rd.Read())
{

сразу после фигурной скобки, или изменить линию кода
rows.Add(row.Clone());
Причина, array это "reference type", познакомиться с описание reference type можно здесь, ключ к пониманию следующий абзац:
With reference types, two variables can reference the same object; therefore, operations on one variable can affect the object referenced by the other variable.
. Точнее, что такое reference type потребует отладчик и работу с MSIL. Вот как описывает reference type MSIL standard:

I.8.2.1 Value types and reference types
There are two kinds of types: value types and reference types.
[...]
 Reference types –A value described by a reference type denotes the location of another
value.
По этой причине, не смотря на то, что вы трижды сместили строку в DataReader, запись каждый раз производилась в один и тот же блок данных, переписывая его, а три записи в неизвестной лист были обращены к одному и тому же блоку.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы