zoukankan      html  css  js  c++  java
  • How can For each...

    Answer:
    I understand the IEnumerator/IEnumerable methods and properties and also how they are interrelated. But I fail to understand from the foreach loop perspective. Say for example, if I say the following line of code, how does the compiler look at foreach loop and break it down to IEnumerable/IEnumerator for every occurance of foreach loop in your code. In other words, what happens under the hood? I tried to go through couple of articles on the web. But they were NOT looked from the foreach loop perspective or I might have failed to understand. Could somebody explain with the example or direct me to any articles that explains clearly. All help is greatly appreciated.

    Answer: To keep it short the compiler doesn't do much. It just translates the foreach code into a while under the hood. Here's an example:

    List<int> list = new List<int>;

    ........

    foreach(int item in list)

    {

    //Do stuff

    }

    Becomes:

    Enumerator<int> enum = ((IEnumerable<int>)list).GetEnumerator();

    enum.Reset();

    while(enum.MoveNext())

    {

    int item = enum.Current;

    //Do stuff

    }

    or something very close to that. The acual code compiled most likely has a try / finally block around the while to dispose the enumerator

    IEnumerable is the base interface for all non-generic collections that can be enumerated. For the generic version of this interface see System.Collections.Generic.IEnumerable<T>. IEnumerable contains a single method, GetEnumerator, which returns an IEnumerator. IEnumerator provides the ability to iterate through the collection by exposing a Current property and MoveNext and Reset methods.

    It is a best practice to implement IEnumerable and IEnumerator on your collection classes to enable the foreach (For Each in Visual Basic) syntax, however implementing IEnumerable is not required. If your collection does not implement IEnumerable, you must still follow the iterator pattern to support this syntax by providing a GetEnumerator method that returns an interface, class or struct. When using Visual Basic, you must provide an IEnumerator implementation, which is returned by GetEnumerator. When developing with C# you must provide a class that contains a Current property, and MoveNext and Reset methods as described by IEnumerator, but the class does not have to implement IEnumerator.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;
    
    namespace CSharpExam
    {
        public class TestInumerable
        {
            public static void Run()
            {
                Person[] peopleArray = new Person[3]
            {
                new Person("Steven", "Xia"),
                new Person("Jim", "Johnson"),
                new Person("Sue", "Rabon"),
            };
    
                People peopleList = new People(peopleArray);
                foreach (Person p in peopleList)
                    Console.WriteLine(p.firstName + " " + p.lastName);
    
    
            }
        }
    
        public class Person
        {
            public Person(string fName, string lName)
            {
                this.firstName = fName;
                this.lastName = lName;
            }
    
            public string firstName;
            public string lastName;
        }
    
        public class People //: IEnumerable
        {
            private Person[] _people;
            public People(Person[] pArray)
            {
                _people = new Person[pArray.Length];
    
                for (int i = 0; i < pArray.Length; i++)
                {
                    _people[i] = pArray[i];
                }
            }
    
            #region IEnumerable 成员
    
            public PeopleEnum GetEnumerator()
            {
                return new PeopleEnum(_people);
            }
    
            #endregion
        }
    
        public class PeopleEnum //: IEnumerator
        {
            public Person[] _people;
    
            // Enumerators are positioned before the first element 
            // until the first MoveNext() call. 
            int position = -1;
    
            public PeopleEnum(Person[] list)
            {
                _people = list;
            }
    
            public bool MoveNext()
            {
                position++;
                return (position < _people.Length);
            }
    
            public void Reset()
            {
                position = -1;
            }
    
    
            public object Current
            {
                get
                {
                    try
                    {
                        return _people[position];
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
        }
    
    }
  • 相关阅读:
    JavaScript获取浏览器高度和宽度值
    机器学习2
    2014.7.23
    2014.7.22
    STM32 定时器
    STM32 外部中断
    STM32--systick延时
    STM32 时钟
    输入捕获
    DAC
  • 原文地址:https://www.cnblogs.com/silva/p/3176303.html
Copyright © 2011-2022 走看看