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