c#内存分配管理大揭秘

youaway 2013-12-09 05:43:10

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。
百思不得其解。请大神分析一下内存处理。
...全文
417 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Phoozyan 2013-12-13
  • 打赏
  • 举报
回复
另外,很多东西我们之前也是不知道的,多研究未知的疑惑比什么都想别人告诉要好很多。
Phoozyan 2013-12-13
  • 打赏
  • 举报
回复
原因很简单,但是容易被普通程序员忽略: 1.ToList()和AsEnumerable是有区别的。如楼上所说。前者创建新的List<>对象,后者返回原对象的引用。 2.当运行到第二次时,由于未跳出方法域,listp和Jps在栈上一直存在,故.NET机制会重新引导对象引用(第二次listp的引用未曾改变),而不再在栈上创建新的对象名。从而导致第二次可以删除。 简单画一下内存图便知。
小猪八Q 2013-12-10
  • 打赏
  • 举报
回复
你的问题我已经重现了,确实是这么回事,这个应该是linq的延迟处理的原因 修改1: IEnumerable<IGrouping<string, JPropertyInfo>> Jps = Propertys.SelectMany(u => u.Propertyies.Where(w => w.Index == n)) .GroupBy(p => p.Property.Path).ToList();//只查询到一个结果,即Count=1 或者 修改2: listp.RemoveAll(u => u.Key == Jpropertys.Key);
claymore1114 2013-12-10
  • 打赏
  • 举报
回复
Linq的扩展方法有许多需要注意的 Where //yield return 返回对象跟原 引用不同 Select//同上 SelectMany//同上 ToList // new List<> 返回的引用不同 AsEnumerable //直接返回, 引用相同 ElementAt //分情况 1 如果是 IList 则返回索引 2 如果不是IList,则 遍历 yield return 具体可以 反编译 看看linq实现....
youaway 2013-12-10
  • 打赏
  • 举报
回复
@caozhy
youaway 2013-12-09
  • 打赏
  • 举报
回复
先睡觉,明早见着再回复详谈。
youaway 2013-12-09
  • 打赏
  • 举报
回复
由于IEnumerable没有删除方法,就如此转换删除后再转换回去。
youaway 2013-12-09
  • 打赏
  • 举报
回复
引用 5 楼 wpfLove 的回复:
感觉你的理解有问题,list的RemoveAll是指移除所有符合条件的项,也就是说,每次while循环都是溢出jps的第一项 你怎么又说第二次才是u==jps.ElementAt(0)为true 感觉你的逻辑有点不清楚
是这样的啊,如果Jps查询有多项,我就先使用Jps.ElementAt(0),来进行操作,然后删除listp.RemoveAll(u => u == Jps.ElementAt(0)); 那么也就可以继续循环其他项了。但是现在Jps就一个元素,使用后RemoveAll里的Lamda竟然为false,也就是没删除掉,然后又执行一次,第二次再到此处时,竟然为true了,然后循环才结束。 不知道我的表达你有没有明白。
小猪八Q 2013-12-09
  • 打赏
  • 举报
回复
感觉你的理解有问题,list的RemoveAll是指移除所有符合条件的项,也就是说,每次while循环都是溢出jps的第一项 你怎么又说第二次才是u==jps.ElementAt(0)为true 感觉你的逻辑有点不清楚
youaway 2013-12-09
  • 打赏
  • 举报
回复
引用 3 楼 owen_0075 的回复:
你编译的过吗
引用 2 楼 wpfLove 的回复:
你这代码有点问题吧,怎么先While,后定义的Jps变量~~~
引用 2 楼 wpfLove 的回复:
你这代码有点问题吧,怎么先While,后定义的Jps变量~~~
不好意思啊,各位这是黏贴复制组合的伪代码,当时急着出去办事,一时匆忙没审查。 应该是下面这样的:


IEnumerable<IGrouping<string,JPropertyInfo>> Jps=               
Propertys.SelectMany(u => u.Propertyies.Where(w => w.Index == n))              
.GroupBy(p=>p.Property.Path);//只查询到一个结果,即Count=1
while(Jps.Count()>0)
{
 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,才给删除掉,第一次RemoveAll里的判断为false。
owen_0075 2013-12-09
  • 打赏
  • 举报
回复
你编译的过吗
小猪八Q 2013-12-09
  • 打赏
  • 举报
回复
你这代码有点问题吧,怎么先While,后定义的Jps变量~~~
threenewbee 2013-12-09
  • 打赏
  • 举报
回复
while下面没有括号 只有第一条语句是在做循环。

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧