Adding an item to a dictionary results in a NullReferenceException
The following code has only thrown a NullReferenceException a handful of times over the last several months, but I'm not exactly sure why. The code isn't mine, but it looks pretty straight forward to me.
Type pageType = page.GetType();
if (_pages.TryGetValue(pageType, out value))
return value;
// The following line throws the exception
return _pages[pageType] = new MyPage(_section.Pages[page]);
[NullReferenceException: Object reference not set to an instance of an object.] System.Collections.Generic.Dictionary
2.Insert(TKey key, TValue value, Boolean add) +210 System.Collections.Generic.Dictionary
2.set_Item(TKey key, TValue value) +11
The only thing I can think of is that pageType
is null when it's being used as a dictionary key, but apparently that is not possible.
The code that calls it is simple:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_mypage = GetPage();
}
I also thought that the error might be with the _section.Pages
, but section is never null and never开发者_如何学运维 sets anything. If .Pages[page]
returns null, the MyPage
constructor simply returns. So what am I missing?
I had this issue and it turned out to be threading related.
By placing a sync lock around the line that inserts into the dictionary you can protect against the error:
This must be added as a class level definition:
private static object _sync = new object();
This is the insert statement surrounded by a sync lock:
lock (_sync)
{
return _pages[pageType] = new MyPage(_section.Pages[page]);
}
This is the post that solved it for me: Throw a NullReferenceException while calling the set_item method of a Dictionary object in a multi-threading scenario
I think it is throwing an exception because there is no element in the dictionary for the key pageType, and the accessor is returning null.
Try
MyPage newPage = new MyPage(_section.Pages[page]);
_pages.Add(pageType, newPage);
return newPage;
or if you are trying to reuse the entry if it exists:
MyPage newPage = new MyPage(_section.Pages[page]);
if (_pages.ContainsKey(pageType))
_pages[pageType] = newPage;
else
_pages.Add(pageType, newPage);
maybe the dictionary user defines somewhere else a custom IEqualityComparer that fails under some circumstances. Check where the code creates the dictionary to see if a custom comparer is passed. Maybe the comparer as well can be null, but this means this code never run...
I would split them out for clarity, then see whats happening.
var section = _section.Pages[page];
var newPage = new MyPage(section);
_pages.Add(pageType,newPage);
return newPage;
I think either _pages or pageType object is null. Another chance is _section object.
Since TryGetValue didn't failed it looks to be caused by _section.Pages[page]. Since exception comes from Dictionary.Insert method, most probably, it's caused by equality/hash code implementation for the page. Are there custom implementations of IEqualityComparer or Equals/GetHashCode methods for page type? How these dictionaries are created?
精彩评论