1

我遇到一个奇怪的问题。如下所示的代码,列表包含很多项目。代码list.Count == 0;有时会调用GetHashCode列表中项目的函数。

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;
          }
    }
}

我不知道为什么会发生这种情况?

非常感谢您提供的任何信息。

列表有时不包含任何内容,列表计数为 0。列表包含 NHibernate 项。[NHibernate.Collection.Generic.PersistentGenericBag]

4

1 回答 1

3

正如 Shad 在评论中所说,这与您的IList<T>. 我去检查了源代码,PersistentGenericBag<T>它看起来像这样:

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

PersistentBag看起来像这样:

public class PersistentBag : AbstractPersistentCollection, IList { }

Count属性在此类中定义,PersistentBag如下所示:

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

wherebag是一个简单IListCachedSize仅仅是一个int属性。所以一切都与ReadSizewhich 的定义有关AbstractPersistentCollection,如下所示:

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;
}

session变量是 type ISessionImplementor,所以一切都取决于它是如何实现的。应该是从包中获取项目的GetCollectionEntry(bag)调用(包是允许重复元素的集合结构),它必须在检索它之前执行一些相等性检查,而这又必须调用GetHashCode该项目。

我不知道他们对这一切做了什么,但这与上述方法有关。

参考:
PersistentGenericBag
PersistentBag
AbstractPersistentCollection

于 2013-11-03T13:41:55.093 回答