C# IList<;T>;Count属性调用GetHashCode()(使用NHibernate)
我遇到了一个奇怪的问题。 正如下面显示的代码,列表包含很多项。 代码C# IList<;T>;Count属性调用GetHashCode()(使用NHibernate),c#,nhibernate,ilist,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
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;
}
}
}
publicstaticbool为空(此IList列表)
{
if(list==null)
返回true;
返回列表。计数==0;
}
类项目
{
int-id;
int版本;
公共覆盖int GetHashCode()
{
未经检查
{
返回(Id*397)^版本;
}
}
}
我不知道为什么会这样
非常感谢您提供的任何信息
列表有时不包含任何内容,列表的计数为0。
该列表包含NHibernate项。
[NHibernate.Collection.Generic.PersistentGenericBag]正如Shad在评论中所说,它与您的
IList的实现有关。我去查看了PersistentGenericBag
的源代码,它看起来是这样的:
public class PersistentGenericBag<T> : PersistentBag, IList<T> { }
public class PersistentBag : AbstractPersistentCollection, IList { }
Count
属性在此类PersistentBag
中定义,如下所示:
public int Count
{
get { return ReadSize() ? CachedSize : bag.Count; }
}
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;
}
其中,bag
是一个简单的IList
,而CachedSize
仅仅是一个int
属性。所以一切都与ReadSize
有关,它在AbstractPersistentCollection
中定义,看起来像:
public int Count
{
get { return ReadSize() ? CachedSize : bag.Count; }
}
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
我不知道他们对这一切做了什么,但这与上述方法有关
参考文献:
使用堆栈跟踪查找调用方否,列表。Count
不会调用GetHashCode
。是什么让你这么想的?这还取决于IList的具体实现,而不是一些模糊的信息痕迹,你为什么不发布一个相关的代码来说明这个问题呢?请参阅。@MarcGravel列表是PersistentGenericBag。我想我知道发生了什么。非常感谢。由于延迟加载,PersistentGenericBag的Count属性可能会触发数据库请求。