Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Я не знаю, работало ли это, потому что я вполне уверен, что ключи не хранятся в порядке, они добавляются, но Вы могли бросить KeysCollection к Списку и затем получить последний ключ в списке..., но это будет стоить взглянуть.
Единственная другая вещь, о которой я могу думать, состоит в том, чтобы сохранить ключи в поиске, перечисляют и добавляют ключи к списку перед добавлением их к словарю..., это не симпатичный tho.
Путем Вы сформулировали вопрос, приводит меня полагать, что интервал в Словаре содержит "позицию" объекта по Словарю. Оценка от утверждения, что ключи не хранятся в порядке, что они добавляются, если бы это корректно, который означал бы это ключи. Количество (или.Count - 1, если Вы используете основанный на нуле) должно все еще всегда быть количеством вводимого в последний раз ключа?
, Если это корректно, там любая причина, Вы не можете вместо этого использовать Dictionary< интервал, string> так, чтобы можно было использовать mydict [mydict. Ключи. Количество]?
Я думаю, что можно сделать что-то вроде этого, синтаксис мог бы быть неправильным, не использовали C# в некоторое время, Чтобы получить последний объект
Dictionary<string, int>.KeyCollection keys = mydict.keys;
string lastKey = keys.Last();
или использовать Max вместо В последний раз для получения макс. значения, я не знаю, какой соответствует коду лучше.
Почему Вы только не расширяетесь, класс словаря для добавления в последнем ключе вставил свойство. Что-то как следующее, возможно?
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);
}
}
Вы могли всегда делать это:
string[] temp = new string[mydict.count];
mydict.Keys.CopyTo(temp, 0)
int LastCount = mydict[temp[mydict.count - 1]]
, Но я не рекомендовал бы его. Нет никакой гарантии, что последний вставленный ключ будет в конце массива. Упорядочивание для Ключей на MSDN является неуказанным, и подлежит изменению. В моем очень кратком тесте это, действительно кажется, в порядке вставки, но Вы были бы более обеспеченным зданием в надлежащей бухгалтерии как стек - как Вы предполагаете (хотя я не вижу потребность структуры на основе Ваших других операторов) - или единственный переменный кэш, если просто необходимо знать последний ключ.
Можно использовать OrderedDictionary.
Представляет набор пар ключ/значение, которые доступны ключом или индексом.
Я соглашаюсь со второй частью ответа Patrick. Даже если в некоторых тестах это, кажется, сохраняет порядок вставки, документация (и нормальное поведение для словарей и хешей) явно указывает, что упорядочивание является неуказанным.
Вы просто напрашиваетесь на неприятности в зависимости от упорядочивания ключей. Добавьте свою собственную бухгалтерию (как Patrick сказал, просто единственная переменная для последнего добавленного ключа) быть уверенным. Кроме того, не соблазняйтесь всеми методами такой настолько Последние и Max на словаре, как те, вероятно, относительно ключевого компаратора (я не уверен в этом).
Словарь - это хеш-таблица, поэтому вы не знаете порядок вставки!
Если вы хотите знаю последний вставленный ключ, я бы предложил расширить словарь, включив в него значение 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 ()
, поэтому для преодоления этого вам придется должен хранить упорядоченный список вставленных ключей.
Если вы решите использовать опасный код, который может быть поврежден, эта функция расширения получит ключ из 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);
}
};