关于foreach的一个小局限
2008-03-14 13:37 TTlive 阅读(138) 评论(0) 编辑 收藏 举报foreach是C#相对于C/C++在程序循环结构的实现中引入的一个新的关键词,其作用是遍历一个集合中的每一个元素。
例如,我们有一个DropDownList类型的下拉框ddlItems,把遍历它的每一项,我们可以写如下代码:
string temp="";
for (int i = 0; i < ddlItems.Items.Count; i++)
{
temp += ddlItems.Items[i].Text;
}
这里,需要借用一个循环变量i。在C#中,这样的循环可以利用foreach来实现,而不需要借助循环变量:
string temp="";
foreach (ListItem li in ddlItems.Items)
{
temp += li.Text;
}
例如,我们有一个DropDownList类型的下拉框ddlItems,把遍历它的每一项,我们可以写如下代码:
string temp="";
for (int i = 0; i < ddlItems.Items.Count; i++)
{
temp += ddlItems.Items[i].Text;
}
这里,需要借用一个循环变量i。在C#中,这样的循环可以利用foreach来实现,而不需要借助循环变量:
string temp="";
foreach (ListItem li in ddlItems.Items)
{
temp += li.Text;
}
呵呵,这样写,虽然是没了i,却多了一个ListItem的对象引用。但这样写的好处也是显而易见的,程序员不必担心漏了或者循环变量越界问题。所以,一直很喜欢用foreach,直到有一天,我写了如下代码:
foreach (ListItem li in ddlItems.Items)
{
if (li.Text == "Delete Me") ddlItems.Items.Remove(li);
}
这段代码想要把ddlItems的列表里的项的Text属性为"Delete Me"的项删掉,结果,系统在编译时通过,在运行时,却抛出了异常。原来,使用foreach的时候,要求全集不能有变化。因为删掉了符合条件的li,所以,导致ddlItems.Items发生了变化,致使foreach抛出异常。解决方法也很简单,回到原始的方式上来,把代码改成以下形式,就OK了:
for (int i = ddlItems.Items.Count; i >= 0; i--)
{
if (ddlItems.Items[i].Text == "Delete Me") ddlItems.Items.RemoveAt(i);
}
这里要注意的,i的值必须是从最大往最小递减,因为在删除一个项后,如果这个项不是最后一个,那么,其后面的项的index都会减1,这样,递增时计算就会出错。