• 黑马程序员-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,做forforeach的循环

                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的日志 - 网易博客

  • 相关阅读:
    定时器
    js中script的上下放置区别 , Dom的增删改创建
    函数声明与应用
    常规选择器
    表格的制作
    流程控制
    For循环
    洛谷P1419寻找段落
    洛谷P1021邮票面值设计
    洛谷P3119草鉴定
  • 原文地址:https://www.cnblogs.com/xsj891107/p/3666522.html
Copyright © 2020-2023  润新知