遍历的时候用for好还是用foreach好?
我知道两个都能遍历,并且觉得foreach比较严谨一点,但是我想知道一个全面的解释,谢谢
我知道两个都能遍历,并且觉得foreach比较严谨一点,但是我想知道一个全面的解释,谢谢
解决方案 »
- 如何才能向DropDownList的文本窗口中输入文字,就像文本框一样可以输入文字。
- 在类库中ADAPTER怎么写?
- windows验证
- asp.net导入数据到数据库中,没有任何格式限定
- 该组件上的 GetValue 操作失败,生成错误代码 0x80070057。
- 请教,datagrid图形化绑定的问题!
- gridview 多行编辑模式下不能应用 AutoCompleteExtender吗?
- 导出Excel 2003可以2007却不可以的代码分析.
- Asp.net <%$ %> 符号是什么意思?
- 急需解决的一个关于图片的问题。。!!!!!
- .net中字符串替换问题,请教各位。
- 点击Gridview的链接弹出一个框的问题
foreach用于遍历实现IEnumerable接口的集合的元素
简洁
http://www.51testing.com/?uid-70557-action-viewspace-itemid-7949
foreach 是与 ienumerable 一起用的,至少有两个负担:1,即使循环体是空的,也涉及对 ienumerator 成员的调用
2,有时候存在隐式的类型转换foreach(object o in numbers) // numbers 是 int[]
每个元素都要装箱foreach(int n in objects) // objects 是 object[]
每个元素都要拆箱不过我们现在有了 ienumerable<t>,情况好很多。所以我觉得是for更快。但是我没做测试,全是猜
using System.Diagnostics;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string s = new string('中', 50000);
string r = "";
Stopwatch watch = new Stopwatch();
watch.Start();
foreach (char c in s)
r += c;
//for (int i = 0; i < 50000; i++)
// r += s[i];
watch.Stop();
div1.InnerText = watch.ElapsedMilliseconds.ToString() + "毫秒";
}
}
有装箱拆箱么?不是说.net 1.x的时候会在foreach中对值类型装箱拆箱,.net 2.0(vs2005)的时候这个foreach的效率就不比for差了,因为有了yield关键字。
这样的foreach效率比for低?
那for(int i=0;i<3;i++)与int i=0;for(;i<3;i++)那个效率更高呢。
sdr[0]与sdr["a"]呢?
有得必有失,关键是你怎么衡量得失。牺牲时间换空间,牺牲空间换时间,牺牲空间时间换代码可读性等等。
foreach是只读的,如果在foreach中修改正在遍历的容器会抛出InvildOperation异常。
这这句话对系统提供的容器有效。如果自定义的容器中实现了相应的机制也有效。可以用Reflector查看一下系统提供的一些容器像List、Dictionary,会发现其中有个成员_version,每一次对容器的修改都会让_version值增加,在容器的遍历器中会检查_version的值如果值发生改变就会抛出异常。这应该是为了多线程考虑,当然也不全是,在遍历的实现中会保存容器的尺寸、当前访问的位置等信息以对下一次访问进行合理性检查。如果对容器进行修改这些信息就会过时,对下一次访问的合理性检查就有可能失效。会带来意想不到的结果。
foreach的实现用到了遍历器,遍历器需要消耗额外的空间与CPU的计算能力,如果有装箱和拆箱就更费事了。当然有人会说有yield。但是为了让循环的每次都执行对应yield语句是否需要额外的数据结构,这会带来比遍历器更多的空间消耗。for语句没有这些额外的机制,循环控制由编码者完全控制,所以可以在循环内部对遍历对象进行修改,只要能够保证逻辑不出错。for语句的内部实现上来说不会需要额外的空间和计算能力。这并不能说for语句比foreach更有效。需要根据情况来定。对于数组或者其它连续存储的数据结构,在循环内部使用索引器进行访问,一般会使用偏移进行定位,这确实比较高效。但是对于非连续存储的数据结构,由于使用索引器进行定位不是靠偏移,有额外的计算工作。当然也有人在for里边使用遍历器进行访问,这还不如使用foreach。所以能用foreach就用foreach,必须用for的时候才能用for。foreach简单易用性能损失可以忽略,如果为了提高性能,可以对算法进行优化,不用在这上面打主意。如果您已经到了不能忍受CLR带来的性能损失时请拒绝CLR。
请看这样一段代码
public void CloseAllPages()
{
PageForm[] pageA = _visiblePageList.ToArray();
for(int i = 0; i < pageA.Length; i++)
{
pageA[i].Close();
}
}
_visiblePageList是一个浏览器页面窗口链表。在这里就不能使用foreach。
在页面文件关闭时会将自身从页面窗口链表中移除。这里就存在隐含修改容器内容的情况。事件驱动中有很多隐含的情形,如何理解并对事件加以合理利用将会大大提高效率。如果不习惯事件驱动,这些隐含操作将会带来巨大的麻烦。