日期:2014-05-17  浏览次数:20868 次

c#内存分配管理大揭秘

while(Jps.Count()>0)
IEnumerable<IGrouping<string,JPropertyInfo>> Jps= 
              Propertys.SelectMany(u => u.Propertyies.Where(w => w.Index == n))
              .GroupBy(p=>p.Property.Path);//只查询到一个结果,即Count=1
IGrouping<string, JPropertyInfo> Jpropertys = Jps.ElementAt(0);
foreach(JPropertyInfo jp in Jpropertys )
{
   //Dosomething
}
 List<IGrouping<string, JPropertyInfo>> listp = Jps.ToList();
 listp.RemoveAll(u => u == Jps.ElementAt(0));
 Jps=listp.AsEnumerable();

按照理论来说,应该while循环只循环一次才对啊,为什么循环了两次,第二次才u == Jps.ElementAt(0)为true,才给删除掉,第一次为false。
百思不得其解。请大神分析一下内存处理。

------解决方案--------------------
原因很简单,但是容易被普通程序员忽略:
1.ToList()和AsEnumerable是有区别的。如楼上所说。前者创建新的List<>对象,后者返回原对象的引用。
2.当运行到第二次时,由于未跳出方法域,listp和Jps在栈上一直存在,故.NET机制会重新引导对象引用(第二次listp的引用未曾改变),而不再在栈上创建新的对象名。从而导致第二次可以删除。
简单画一下内存图便知。