Доступ к Словарю. Ключ ключей через числовой индекс

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

153
задан user2771704 7 April 2015 в 12:16
поделиться

9 ответов

Я не знаю, работало ли это, потому что я вполне уверен, что ключи не хранятся в порядке, они добавляются, но Вы могли бросить KeysCollection к Списку и затем получить последний ключ в списке..., но это будет стоить взглянуть.

Единственная другая вещь, о которой я могу думать, состоит в том, чтобы сохранить ключи в поиске, перечисляют и добавляют ключи к списку перед добавлением их к словарю..., это не симпатичный tho.

2
ответ дан lomaxx 23 November 2019 в 22:05
поделиться

Путем Вы сформулировали вопрос, приводит меня полагать, что интервал в Словаре содержит "позицию" объекта по Словарю. Оценка от утверждения, что ключи не хранятся в порядке, что они добавляются, если бы это корректно, который означал бы это ключи. Количество (или.Count - 1, если Вы используете основанный на нуле) должно все еще всегда быть количеством вводимого в последний раз ключа?

, Если это корректно, там любая причина, Вы не можете вместо этого использовать Dictionary< интервал, string> так, чтобы можно было использовать mydict [mydict. Ключи. Количество]?

3
ответ дан Jeremy Privett 23 November 2019 в 22:05
поделиться

Я думаю, что можно сделать что-то вроде этого, синтаксис мог бы быть неправильным, не использовали C# в некоторое время, Чтобы получить последний объект

Dictionary<string, int>.KeyCollection keys = mydict.keys;
string lastKey = keys.Last();

или использовать Max вместо В последний раз для получения макс. значения, я не знаю, какой соответствует коду лучше.

5
ответ дан Juan 23 November 2019 в 22:05
поделиться

Почему Вы только не расширяетесь, класс словаря для добавления в последнем ключе вставил свойство. Что-то как следующее, возможно?

public class ExtendedDictionary : Dictionary<string, int>
{
    private int lastKeyInserted = -1;

    public int LastKeyInserted
    {
        get { return lastKeyInserted; }
        set { lastKeyInserted = value; }
    }

    public void AddNew(string s, int i)
    {
        lastKeyInserted = i;

        base.Add(s, i);
    }
}
8
ответ дан VMAtm 23 November 2019 в 22:05
поделиться

Вы могли всегда делать это:

string[] temp = new string[mydict.count];
mydict.Keys.CopyTo(temp, 0)
int LastCount = mydict[temp[mydict.count - 1]]

, Но я не рекомендовал бы его. Нет никакой гарантии, что последний вставленный ключ будет в конце массива. Упорядочивание для Ключей на MSDN является неуказанным, и подлежит изменению. В моем очень кратком тесте это, действительно кажется, в порядке вставки, но Вы были бы более обеспеченным зданием в надлежащей бухгалтерии как стек - как Вы предполагаете (хотя я не вижу потребность структуры на основе Ваших других операторов) - или единственный переменный кэш, если просто необходимо знать последний ключ.

6
ответ дан Patrick 23 November 2019 в 22:05
поделиться

Можно использовать OrderedDictionary.

Представляет набор пар ключ/значение, которые доступны ключом или индексом.

57
ответ дан Andrew Peters 23 November 2019 в 22:05
поделиться

Я соглашаюсь со второй частью ответа Patrick. Даже если в некоторых тестах это, кажется, сохраняет порядок вставки, документация (и нормальное поведение для словарей и хешей) явно указывает, что упорядочивание является неуказанным.

Вы просто напрашиваетесь на неприятности в зависимости от упорядочивания ключей. Добавьте свою собственную бухгалтерию (как Patrick сказал, просто единственная переменная для последнего добавленного ключа) быть уверенным. Кроме того, не соблазняйтесь всеми методами такой настолько Последние и Max на словаре, как те, вероятно, относительно ключевого компаратора (я не уверен в этом).

4
ответ дан VMAtm 23 November 2019 в 22:05
поделиться

Словарь - это хеш-таблица, поэтому вы не знаете порядок вставки!

Если вы хотите знаю последний вставленный ключ, я бы предложил расширить словарь, включив в него значение LastKeyInserted.

Например:

public MyDictionary<K, T> : IDictionary<K, T>
{
    private IDictionary<K, T> _InnerDictionary;

    public K LastInsertedKey { get; set; }

    public MyDictionary()
    {
        _InnerDictionary = new Dictionary<K, T>();
    }

    #region Implementation of IDictionary

    public void Add(KeyValuePair<K, T> item)
    {
        _InnerDictionary.Add(item);
        LastInsertedKey = item.Key;

    }

    public void Add(K key, T value)
    {
        _InnerDictionary.Add(key, value);
        LastInsertedKey = key;
    }

    .... rest of IDictionary methods

    #endregion

}

Однако вы столкнетесь с проблемами при использовании .Remove () , поэтому для преодоления этого вам придется должен хранить упорядоченный список вставленных ключей.

17
ответ дан 23 November 2019 в 22:05
поделиться

Если вы решите использовать опасный код, который может быть поврежден, эта функция расширения получит ключ из Dictionary в соответствии с его внутренней индексацией (которая для Mono и .NET в настоящее время выглядит в том же порядке, что и при перечислении свойства Keys ).

Намного предпочтительнее использовать Linq: dict.Keys.ElementAt (i) , но эта функция будет повторять O (N); следующее - O (1), но со снижением производительности отражения.

using System;
using System.Collections.Generic;
using System.Reflection;

public static class Extensions
{
    public static TKey KeyByIndex<TKey,TValue>(this Dictionary<TKey, TValue> dict, int idx)
    {
        Type type = typeof(Dictionary<TKey, TValue>);
        FieldInfo info = type.GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance);
        if (info != null)
        {
            // .NET
            Object element = ((Array)info.GetValue(dict)).GetValue(idx);
            return (TKey)element.GetType().GetField("key", BindingFlags.Public | BindingFlags.Instance).GetValue(element);
        }
        // Mono:
        info = type.GetField("keySlots", BindingFlags.NonPublic | BindingFlags.Instance);
        return (TKey)((Array)info.GetValue(dict)).GetValue(idx);
    }
};
4
ответ дан 23 November 2019 в 22:05
поделиться
Другие вопросы по тегам:

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