开发者

Adding an item to a dictionary results in a NullReferenceException

开发者 https://www.devze.com 2023-02-20 03:00 出处:网络
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 t

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.Dictionary2.Insert(TKey key, TValue value, Boolean add) +210 System.Collections.Generic.Dictionary2.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?

0

精彩评论

暂无评论...
验证码 换一张
取 消