黑马程序员-for和foreach
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***第一种情况************************************************");
string[] array11 = new string[] { "111", "222", "333" };
string[] array12 = new string[] { "111", "222", "333" };
for (int i = 0; i < array11.Length; i++)
{
Console.WriteLine(array11[i]);
}
Console.WriteLine("=========================");
foreach (string s in array12)
{
Console.WriteLine(s);
}
/*结果
111
222
333
=========================
111
222
333
*/
//都是根据length来对数据进行循环
//不同的是foreach里自动对array进行index + 1的操作来循环,而for则是自己的代码控制的
Console.WriteLine("***第二种情况************************************************");
string[] array21 = new string[] { "111", "222", "333" };
string[] array22 = new string[] { "111", "222", "333" };
for (int i = 0; i < array21.Length; i++)
{
Console.WriteLine(array21[i]);
array21 = new string[] { "AAA", "BBB", "CCC" };
}
Console.WriteLine("=========================");
foreach (string s in array22)
{
Console.WriteLine(s);
array22 = new string[] { "AAA", "BBB", "CCC" };
}
/*结果
111
BBB
CCC
=========================
111
222
333
*/
//不一样了吧,看来在foreach内部的循环中对 源数据的更改 不是即时生效的
//在foreach(...)循环里尽量不要更改 操作的源数据
Console.ReadKey();
}
}
namespace for_foreach2
{
class Program
{
static void Main(string[] args)
{
//使用测试类E,做for和foreach的循环
string[] array31 = new string[] { "111", "222", "333" };
E e = new E(array31);
foreach (string s in e)
{
Console.WriteLine(s);
}
/*result
333
222
111
Dispose here!
*/
//差异出现了,这次是按照倒序的方式,而且还自动调用了Dispose方法!
Console.ReadKey();
}
}
//根据MS的参考,能在foreach上做循环的只能是实现了IEnumerable接口。
//(事实上,System.Array也是实现了IEnumerable接口的)
//这儿做一个在IEnumerable上的循环
public class E : System.Collections.IEnumerable
{
private InnerEnumerator inner;
public E(string[] array)
{
this.inner = new InnerEnumerator(array);
}
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return this.inner;
}
#endregion
private class InnerEnumerator : IEnumerator, IDisposable
{
private string[] s;
private int currentIndex;
public InnerEnumerator(string[] array)
{
this.s = array;
this.Reset();
}
#region IEnumerator Members
//Reset index to original(重置索引为原始的)
public void Reset()
{
this.currentIndex = s.Length - 1;
}
//Get Current object inner
public object Current
{
get
{
object o = this.s[this.currentIndex];
this.currentIndex--;
return o;
}
}
//Is there has any other object in the array?
public bool MoveNext()
{
if (this.currentIndex < 0)
{
return false;
}
return true;
}
#endregion
#region IDisposable Members
//Dispose Here()
public void Dispose()
{
Console.WriteLine("Dispose here!");
}
#endregion
}
}
}
综合上面,得出如下结论:
1.for循环并不依赖于数组或其他形式的组式数据结构,只是简单的
在调用了代码后,进行一个判断,判断是否要继续。
(非常类似于do..while和while循环--在这里不作具体分析了^_^~~)
2.foreach循环如果作用在一个基于System.Array的类型之上的数组的话,编译器会自动优化成与for循环非常类似
的代码,只是调用的指命有细微的差别,并且检查(包括编译阶段和运行时)会比for严格的多
3.foreach循环作用在一个非System.Array类型上(且一定要是实现了IEnumerable接口的类),会先调用
IEnumerable.GetEnumerator()方法获取一个Enumertor实例,再在获取的Enumertor实例上调用
GetCurrent()和MoveNext()方法,最后判断如果Enumertor实例如果实现了IDispose接口,就自动调用
IDispose.Dispose()方法!
那么我们应该分别在那些地方用for和foreach捏
建议:
1.在有对所循环的本体(System.Array)做赋值操作时,尽量不要用Foreach()。
2.foreach比for更灵活。(可在MoveNext()和GetCurrent()里编写自己的代码).
自己编写的类如果实现了IEnumerable接口的话,就可以用foreach循环了,而不管内部是否有一个真实的数组,
并且可以自定义循环的规则。
3.从OO的原则看,foreach循环更适于多数情况的使用
(事实上,foreach的实现是典型的Iterator模式,下面有简单的描述它的好处)
想用统一的调用循环接口时,foreach是最佳的选择
(MS有很多类就是这样的,例如前面提到的DataRowCollection.)
参考至:C#里for和foreach的区别 - lyh830612的日志 - 网易博客
黑马程序员-for和foreach的更多相关文章
- 黑马程序员——【Java高新技术】——代理
---------- android培训.java培训.期待与您交流! ---------- 一.“代理概述”及“AOP概念” (一)代理概述 1.问题:要为已存在的多个具有相同接口的目标类的各个方法 ...
- 黑马程序员+SQL基础(上)
黑马程序员+SQL基础 ---------------<a href="http://edu.csdn.net"target="blank">ASP ...
- 黑马程序员+Winform基础(上)
黑马程序员+Winform基础 ---------------<a href="http://edu.csdn.net"target="blank"> ...
- 黑马程序员—C语言的函数、数组、字符串
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.函数 定义:函数是代码复用的一种机制. 函数的基本语法: 返回类型 函数名 ( 参数类型 参 ...
- 黑马程序员:Java基础总结----泛型(高级)
黑马程序员:Java基础总结 泛型(高级) ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 泛型(高级) 泛型是提供给javac编译器使用的,可以限定集合中的输入类型 ...
- 黑马程序员:Java基础总结----类加载器
黑马程序员:Java基础总结 类加载器 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个 ...
- 黑马程序员:Java基础总结----静态代理模式&动态代理
黑马程序员:Java基础总结 静态代理模式&动态代理 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public class Ts { ...
- 黑马程序员:Java基础总结----枚举
黑马程序员:Java基础总结 枚举 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 枚举 为什么要有枚举 问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别 ...
- 黑马程序员:Java基础总结----反射
黑马程序员:Java基础总结 反射 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...
随机推荐
- C++例题1:输出可打印字符
#include<iostream>#include<stdlib.h>#include<cctype>int main(){ int i;char a=0; fo ...
- Zabbix的集中式监控
相对于传统的ZABBIX硬件系统级监控(CPU,内存,硬盘,网卡),应用级的监控就显得有些复杂了. 如果对不同的应该来不同的应用,配置会很多的. 如果我们能在一个指定的AGENT上监控所有的APACH ...
- Struts2的注解功能
我们知道通常情况下,Struts2是通过struts.xml配置的.但是随着系统规模的加大我们需要配置的文件会比较大,虽然我们可以根据不同的系统功能将不同模块的配置文件单独书写,然后通过<inc ...
- Arrays.sort的粗略讲解
排序算法,基本的高级语言都有一些提供.C语言有qsort()函数,C++有sort()函数,java语言有Arrays类(不是Array).用这些排序时,都可以写自己的排序规则. Java API对A ...
- Linux日志文件系统(EXT4、XFS、JFS)及性能分析
Ext4 ReiserFS Btrfs 等七种文件系统性能比拼 自上一篇<Ext2 v.s. Ext3 v.s. Ext4 性能比拼> 发布以来,社会各界纷纷来电来函,给出了“Ext4 我 ...
- COJ 2108 Day7-例1
Day7-例1 难度级别:B: 运行时间限制:1000ms: 运行空间限制:256000KB: 代码长度限制:2000000B 试题描述 在计算机中,CPU只能和高速缓存Cache直接交换数据.当 ...
- hiho #1044 : 状态压缩·一
描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市——那座城市即将举行美食节! 但是不幸的是,小Hi和小Ho并没有能够买到很好的火车票—— ...
- MongoDB权限提升漏洞(CVE-2013-4650)
漏洞版本: MongoDB 2.4.0-2.4.4 MongoDB 2.5.0 漏洞描述: CVE ID: CVE-2013-4650 MongoDB是一个高性能,开源,无模式的文档型数据库,是当前N ...
- No row with the given identifier exists[ArtProject.Domains.Users#2]
产生此问题的原因: 有两张表,table1和table2. 产生此问题的原因就是table1里做了关联<one-to-one>或者<many-to-on ...
- Qt入门(9)——Qt中的线程支持
Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法.警告:所有的GUI类(比如,QWidget和它的子类),操作系统核心 ...