简体   繁体   中英

KeyNotFoundException when iterating through Dictionary

I have a seemingly simple piece of code that is consistently throwing an error that I wouldn't expect to be possible:

// Private member
private Dictionary<InputField, bool> m_Completed;

// Later on, during some method
foreach (InputField filter in this.m_Completed.Keys)
    if (this.m_Completed[filter])
        completedCount += 1;

And the error I'm getting:

KeyNotFoundException: The given key was not present in the dictionary

This is coming from the "if" statement in the loop.

To me, this implies that the iterator has become desynchronised from the actual keys of the dict. Is this possible? There is no threading going on.

Is my workflow just wrong? I can think of a few other ways to get my count, but I'd still like to know why my code is throwing an error.

Either InputField or one of its base classes implements GetHashCode in a way such that it won't return the same value for the lifetime of the instance.

This completely breaks the functionality of a Dictionary or an HashSet , which rely on a consistent hash code.

As such, a possible solution would be to make your InputField override GetHashCode and Equals . If it already overrides these, you'll need to fix the implementation.

You'll find great guidelines for proving a proper implementation on Eric Lippert's blog post Guidelines and rules for GetHashCode .

In this case, this is the guideline that seems to be missing from the current implementation:

Guideline: the integer returned by GetHashCode should never change

Ideally, the hash code of a mutable object should be computed from only fields which cannot mutate, and therefore the hash value of an object is the same for its entire lifetime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM