简体   繁体   中英

Weird dictionary ContainsKey issue

Before I start, I'd like to clarify that this is not like all the other somewhat "similar" questions out there. I've tried implementing each approach, but the phenomena I am getting here are really weird.

I have a dictionary where ContainsKey always returns false , even if their GetHashCode functions return the same output, and even if their Equals method returns true .

What could this mean? What am I doing wrong here?

Additional information

The two elements I am inserting are both of type Owner , with no GetHashCode or Equals method. These inherit from a type Storable , which then implements an interface, and also has GetHashCode and Equals defined.

Here's my Storable class. You are probably wondering if the two Guid properties are indeed equal - and yes, they are. I double-checked. See the sample code afterwards.

public abstract class Storable : IStorable
{

    public override int GetHashCode()
    {
        return Id == default(Guid) ? 0 : Id.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as Storable;
        return other != null && (other.Id == Id || ReferenceEquals(obj, this));
    }

    public Guid Id { get; set; }

    protected Storable()
    {
        Id = Guid.NewGuid();
    }

}

Now, here's the relevant part of my code where the dictionary stuff occurs. It takes in a Supporter object which has a link to an Owner .

public class ChatSession : Storable, IChatSession
{

    static ChatSession()
    {
        PendingSupportSessions = new Dictionary<IOwner, LinkedList<IChatSession>>();
    }

    private static readonly IDictionary<IOwner, LinkedList<IChatSession>> PendingSupportSessions;

    public static ChatSession AssignSupporterForNextPendingSession(ISupporter supporter)
    {

        var owner = supporter.Owner;
        if (!PendingSupportSessions.ContainsKey(owner)) //always returns false
        {
            var hashCode1 = owner.GetHashCode();
            var hashCode2 = PendingSupportSessions.First().Key.GetHashCode();

            var equals = owner.Equals(PendingSupportSessions.First().Key);

            //here, equals is true, and the two hashcodes are identical,
            //and there is only one element in the dictionary according to the debugger.
            //however, calling two "Add" calls after eachother does indeed crash.

            PendingSupportSessions.Add(owner, new LinkedList<IChatSession>());
            PendingSupportSessions.Add(owner, new LinkedList<IChatSession>()); //crash
        }

        ...

    }

}

If you need additional information, let me know. I am not sure what kind of information would be sufficient, so it was hard for me to include more.

Guillaume was right. It appears that I was changing the value of one of my keys after it is added to the dictionary. Doh!

Make sure you are passing same object that is stored as key in dictionary. If you are creating new object each time and trying to find key assuming the object is already stored because of similar values, then containsKey returns false. Object comparisons are different than value comparisons.

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