C#: проблема с вложенным словарем

У меня есть приведенный ниже код, предназначенный для создания объекта словаря со следующей конструкцией Dictionary<string<Dictionary<string, string>. По какой-то причине каждый раз, когда я добавляю к нему элемент, текст ключа правильный, но значение (словарь) перезаписывает предыдущее. Вероятно, это лучше объяснить так:

Итерация 1

  • ключ1, словарь1

Итерация 2

  • ключ1, словарь2
  • ключ2, словарь2

Итерация 3

  • ключ1, словарь3

  • ключ2, словарь3

  • ключ3, словарь3

Что вызывает это и как я могу исправить этот код, чтобы он не перезаписывал словарь в каждой записи?

QueryNameUserQueryString = new Dictionary<string, string>();
DialectDictionary = new Dictionary<string, Dictionary<string, string>>();

while (dataBaseConnection.NextRecord())
                {
                if (QueryNameUserQueryString != null)
                    {
                    QueryNameUserQueryString.Clear();
                    }

                string dialect = dataBaseConnection.GetFieldById (0);

                //If no dialect then carry out next iteration
                if (String.IsNullOrEmpty (dialect))
                    {
                    continue;
                    }

                try
                    {
                    dataBaseConnection2.ExecutePureSqlQuery ("SELECT * FROM " + sqlFactoryTable + " WHERE SQL_FACTORY_DIALECT = '" + dialect + "'");
                    }
                catch
                    {
                    dataBaseConnection.Close();
                    dataBaseConnection2.Close();

                    throw;
                    }

                //Do we have query strings for this dialect?
                if (!dataBaseConnection2.HasRows())
                    {
                    continue;
                    }

                //loop through query strings
                while (dataBaseConnection2.NextRecord())
                    {
                    string queryName = dataBaseConnection2.GetFieldById (2);
                    string queryString = dataBaseConnection2.GetFieldById (3);
                    string user = dataBaseConnection2.GetFieldById (4);

                    //create composite key for dictionary
                    string compositeKey = dialect + "," + queryName + "," + user;

                    if (QueryNameUserQueryString != null)
                        {
                        //Construct our query string dictionary
                        QueryNameUserQueryString.Add (compositeKey, queryString);
                        }
                    }

                //If we have a query string dictionary
                if (QueryNameUserQueryString != null)
                    {
                    //Ensure m_dialect dictionary is not null
                    if (DialectDictionary != null)
                        {
                        //Construct our dictionary entry for this dialect
                        DialectDictionary.Add (dialect, QueryNameUserQueryString);
                        }
                    }
                }
            }

person CSharpened    schedule 07.08.2012    source источник
comment
Кажется, вы используете один и тот же экземпляр QueryNameUserQueryString на каждой итерации.   -  person J. Steen    schedule 07.08.2012
comment
Вы добавляете QueryNameUserQueryString несколько раз, что означает, что DialectDictionary будет иметь несколько ссылок на один и тот же объект. Если вы обновите его, изменения будут отражены во всех элементах в DialectDictionary.   -  person Charleh    schedule 07.08.2012
comment
Но поскольку это добавляется к другому объекту словаря, не должно ли оно добавлять в него копию словаря в то время в качестве значения? Я неправильно понимаю, как работает объект словаря?   -  person CSharpened    schedule 07.08.2012
comment
Нет. Вы добавляете ссылку в свой словарь QNUQS. Не глубокая копия. знак равно   -  person J. Steen    schedule 07.08.2012
comment
Нет - передается по ссылке   -  person Charleh    schedule 07.08.2012
comment
Ах я вижу. Что бы вы предложили, это лучший способ исправить это?   -  person CSharpened    schedule 07.08.2012
comment
Ответ JleruOHeP в качестве начала. =) Но на самом деле - вместо этого поместите переменную внутрь области видимости. Таким образом, вы ограничиваете его масштаб, чтобы он мог существовать только один раз за итерацию, а не за все итерации.   -  person J. Steen    schedule 07.08.2012
comment
Спасибо. Я думал, что словарь был сохранен как новый объект при добавлении в родительский словарь.   -  person CSharpened    schedule 07.08.2012


Ответы (2)


Кажется, вы используете один и тот же экземпляр QueryNameUserQueryString на каждой итерации. Когда он добавляется к DialectDictionary, он добавляется как ссылка, а не как копия оригинала.

Чтобы «правильно» решить проблему, я бы переместил объявление вашей переменной QueryNameUserQueryString внутрь области видимости. Таким образом, вы убедитесь, что он может существовать только в рамках одной итерации, а не нескольких. Когда он добавляется в DialectDictionary, ссылка остается в этом словаре, и вы можете безопасно выйти из области видимости.

person J. Steen    schedule 07.08.2012
comment
Принято за более интуитивное решение и объяснение проблемы. - person CSharpened; 07.08.2012

Вы используете один и тот же экземпляр QueryNameUserQueryString каждый раз. Заменять

QueryNameUserQueryString.Clear();

с

QueryNameUserQueryString = new Dictionary<string, string>();
person JleruOHeP    schedule 07.08.2012