对集合遍历并删除的问题

ayun00 2012-07-04 05:36:01
我的代码如下,但是这样 一旦真的删除了对象,那么出错, 请问怎么遍历集合 然后根据条件删除元素?

for (int i = 0; i < AppConfig.MyTcpClient.Count; i++ )
{
TcpClient c = AppConfig.MyTcpClient[i];
if (c == null || c.Connected == false)
{
AppConfig.MyTcpClient.Remove(c);
}
else
{
User u = new User();

u.name = c.Client.RemoteEndPoint.ToString();
u.MyTcpClient = c;

AppConfig.MainFrom.combobox.InvokeIfNeeded((x) => AppConfig.MainFrom.combobox.Items.Add(x), u);
}
}
...全文
560 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangyue4 2012-07-13
  • 打赏
  • 举报
回复
lz的写法应该加上i--
smile636 2012-07-13
  • 打赏
  • 举报
回复
TcpClient c = AppConfig.MyTcpClient[i];
这个查询 应该也比较慢
smile636 2012-07-13
  • 打赏
  • 举报
回复
1.要看你集合的类型
2.删除频繁否(得到回答是频繁)
3.集合多大
4.每次删除的的数量有多大。
链表,并且删除的数目小于留下的数目,14楼的不错!
如果删除的数目很多,直接把不需要删除的拷贝到新链表里去。

还有个问题,用链表的话,每次查询元素,效率比较低,不知道其他地方是保存 socket的ID还是引用?
stonespace 2012-07-07
  • 打赏
  • 举报
回复
安全的写法是:

for (int i = 0; i < AppConfig.MyTcpClient.Count; i++ )
{
TcpClient c = AppConfig.MyTcpClient[i];
if (c == null || c.Connected == false)
{
AppConfig.MyTcpClient.Remove(c);
i--;
continue;//这样
}
else
{
User u = new User();

u.name = c.Client.RemoteEndPoint.ToString();
u.MyTcpClient = c;

AppConfig.MainFrom.combobox.InvokeIfNeeded((x) => AppConfig.MainFrom.combobox.Items.Add(x), u);
}
}
hhddzz 2012-07-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

肯定是不能用RemoveAll ,我又不是删除全部,只是不满足条件了的对象 才删除.
可以预见的增减是很频繁的, 你说的用链表 是怎么弄的?

引用 6 楼 的回复:
这是很基础的操作吧
你这么做肯定是错误的,你删一个就跳过了一个。
比如删掉了3号元素,原来的4号就变成3号了,而你的索引又递增到4,于是原来的4号就被跳过了。
你可以手动地每删一次就把索引复位一次。
或者从后往前……
[/Quote]
不要望文生义,清除所有元素那是Clear,RemoveAll是删除所有满足条件的元素。
dd_zhouqian 2012-07-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

for (int i = 0; i < AppConfig.MyTcpClient.Count; i++ )
{
TcpClient c = AppConfig.MyTcpClient[i];
if (c == null || c……
[/Quote]

ayun00 2012-07-06
  • 打赏
  • 举报
回复
这段代码是可以了,不过 上面也说过 如果 list 比较大的话 这样效率太低

我想用个更好的办法

[Quote=引用 10 楼 的回复:]
引用 9 楼 的回复:

for (int i = AppConfig.MyTcpClient.Count-1; i >=0; i-- )
{
TcpClient c = AppConfig.MyTcpClient[i];
if (c == null || c.Connected == false)
{
AppConfig.MyTcpClient.Remove(c……
[/Quote]
redstone8415 2012-07-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

for (int i = AppConfig.MyTcpClient.Count-1; i >=0; i-- )
{
TcpClient c = AppConfig.MyTcpClient[i];
if (c == null || c.Connected == false)
{
AppConfig.MyTcpClient.Remove(c);
i--;
……
[/Quote]

有没有上机试过!?
tmd456 2012-07-06
  • 打赏
  • 举报
回复
for (int i = AppConfig.MyTcpClient.Count-1; i >=0; i-- )
{
TcpClient c = AppConfig.MyTcpClient[i];
if (c == null || c.Connected == false)
{
AppConfig.MyTcpClient.Remove(c);
i--;
}
else
{
ayun00 2012-07-06
  • 打赏
  • 举报
回复
肯定是不能用RemoveAll ,我又不是删除全部,只是不满足条件了的对象 才删除.
可以预见的增减是很频繁的, 你说的用链表 是怎么弄的?

[Quote=引用 6 楼 的回复:]
这是很基础的操作吧
你这么做肯定是错误的,你删一个就跳过了一个。
比如删掉了3号元素,原来的4号就变成3号了,而你的索引又递增到4,于是原来的4号就被跳过了。
你可以手动地每删一次就把索引复位一次。
或者从后往前遍历并删除,这样就不存在索引的问题了。我以前初学VB6的时候就是用的这种方法。

不过对于List<T>,T[]等结构来说,这些方法都不好,因为你删一个元素就要把后面所有的元素……
[/Quote]
rayyu1989 2012-07-04
  • 打赏
  • 举报
回复
遍历一遍 把要删除的罗列出来 再遍历新数组 移除原来的数组
hhddzz 2012-07-04
  • 打赏
  • 举报
回复
这是很基础的操作吧
你这么做肯定是错误的,你删一个就跳过了一个。
比如删掉了3号元素,原来的4号就变成3号了,而你的索引又递增到4,于是原来的4号就被跳过了。
你可以手动地每删一次就把索引复位一次。
或者从后往前遍历并删除,这样就不存在索引的问题了。我以前初学VB6的时候就是用的这种方法。

不过对于List<T>,T[]等结构来说,这些方法都不好,因为你删一个元素就要把后面所有的元素往前移,这个操作非常耗时。(比如一个列表有100W元素,你删除原来的0号元素,就要把后面100W-1个元素全部前移;然后你再删除原来的1号元素,又要把后面的100W-1-1个元素全部前移……)

一种比较常用的方法是把需要保留的元素移动到列表前端(需要删除的不管,被需要保留的元素覆盖掉),最后缩减容器的长度,这样可以大大减少数据移动的次数(只有需要保留的元素会被移动一次,而上面那种方法需要保留的元素和不需要保留的元素都会被多次移动)。

说了这么多,如果你的容器是List<T>,用List的RemoveAll方法就行了,它用的就是上面那一段描述的方法,效率比你自己一个个删高得多,代码还简洁明了。

当然,如果一开始就预见到增删操作比较频繁,而不怎么要求随机访问,换成链表是最好的。
SQL777 2012-07-04
  • 打赏
  • 举报
回复
删除了对象报什么错
事理 2012-07-04
  • 打赏
  • 举报
回复
for (int i = 0; i < AppConfig.MyTcpClient.Count; i++ )
{
TcpClient c = AppConfig.MyTcpClient[i];
if (c == null || c.Connected == false)
{
AppConfig.MyTcpClient.Remove(c);
i--;
}
else
{
ayun00 2012-07-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
把要删的对象或者位置记在一个集合里,再遍历那个集合一个个删除
[/Quote]

如果 list 比较大 这样不是很慢?

foreach 直接报错
[Quote=引用 1 楼 的回复:]
用 foreach循环
[/Quote]
iyomumx 2012-07-04
  • 打赏
  • 举报
回复
把要删的对象或者位置记在一个集合里,再遍历那个集合一个个删除
tyang258 2012-07-04
  • 打赏
  • 举报
回复
用 foreach循环

110,584

社区成员

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

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

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