Domanda

I get a strange issue. As the code shown below, list contain a lot of items. The code list.Count == 0; sometimes will invoke GetHashCode function of the item in the list.

public static bool IsNullOrEmpty<T>(this IList<T> list)
{
    if (list == null)
        return true;

    return list.Count == 0;
}

class Item
{
    int id;
    int Version;

    public override int GetHashCode()
    {
          unchecked
          {
                 return (Id * 397) ^ Version;
          }
    }
}

I don't know why this could be happened?

Thanks a lot for any infomation.

The list sometime contain nothing, the Count of list is 0. The list contain NHibernate item. [NHibernate.Collection.Generic.PersistentGenericBag]

È stato utile?

Soluzione

As Shad says in comments it has to do with the implementation of your IList<T>. I went and checked source code of PersistentGenericBag<T> and it looks like this:

public class PersistentGenericBag<T> : PersistentBag, IList<T> { }

And PersistentBag looks like this:

public class PersistentBag : AbstractPersistentCollection, IList { }

The Count property is defined in this class PersistentBag which looks like:

public int Count
{
    get { return ReadSize() ? CachedSize : bag.Count; }
}

where bag is a simple IList and CachedSize merely an int property. So everything has got to do with ReadSize which is defined in AbstractPersistentCollection which looks like:

protected virtual bool ReadSize()
{
    if (!initialized)
    {
        if (cachedSize != -1 && !HasQueuedOperations)
        {
            return true;
        }
        else
        {
            ThrowLazyInitializationExceptionIfNotConnected();
            // the below line it has to be.
            CollectionEntry entry = session.PersistenceContext.GetCollectionEntry(this); 
            ICollectionPersister persister = entry.LoadedPersister;
            if (persister.IsExtraLazy)
            {
                if (HasQueuedOperations)
                {
                    session.Flush();
                }
                cachedSize = persister.GetSize(entry.LoadedKey, session);
                return true;
            }
        }
    }
    Read();
    return false;
}

The session variable is of type ISessionImplementor, so everything will depend on how it is implemented. The GetCollectionEntry(bag) should be a call to get the item from the bag (a bag is a collection structure which allows duplicate elements) which will have to perform some equality checks before retrieving it, which in turn will have to call GetHashCode of the item.

I have no idea what they do with all this, but it has got to do with the above method.

References:
PersistentGenericBag
PersistentBag
AbstractPersistentCollection

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top