IList <t> Count属性调用GetHashCode()(使用NHibernate)</t>

时间:2013-11-03 12:51:47

标签: c# nhibernate ilist

我遇到一个奇怪的问题。 如下面显示的代码,列表包含很多项目。 代码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]

1 个答案:

答案 0 :(得分: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; }
}

其中bag是简单IListCachedSize只是int属性。所以一切都与ReadSize中的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

ISessionImplementor变量的类型为GetCollectionEntry(bag),所以一切都取决于它的实现方式。 GetHashCode应该是从包中获取项目的调用(包是允许重复元素的集合结构),在检索它之前必须执行一些相等性检查,这反过来必须调用{{ 1}}项目。

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

参考文献:
PersistentGenericBag
PersistentBag
AbstractPersistentCollection