小议foreach

       今天给一个同事讲一个程序,应该是一个比较基础的程序,但是把我给难住了(哎,才发现自己的基础也滥的可以了),程序大概是这样的:

    public class MyStringArray : IEnumerable

    {

        public IEnumerator GetEnumerator()

        {

            return (IEnumerator)new MyStringArrayEnumerator(this);

        }

        public MyStringArray(params string[] Strings)

        {

            strings = new string[10];

            foreach(string s in Strings)

            {

                strings[ind++] = s;

            }

        }

        public void Add(string addedstr)

        {

            strings[ind++] = addedstr;

        }

        public string this[int strind]

        {

            get

            {

                return strings[strind];

            }

            set

            {

                strings[strind] = value;

            }

        }

        public string[] strings;

        public int ind=0;

    }

 

    public class MyStringArrayEnumerator:IEnumerator

    {

        public MyStringArrayEnumerator(MyStringArray strarr)

        {

            this.strarr = strarr;

            index = -1;

        }

        public bool MoveNext()

        {

            index++;

            if(index>=strarr.strings.Length)

                return false;

            else

                return true;

        }

        public void Reset()

        {

            index = -1;

        }

        public object Current

        {

            get

            {

                return(strarr[index]);

            }

        }

        MyStringArray strarr;

        int index;

    }

 

    class Class1

    {

        [STAThread]

        static void Main(string[] args)

        {      

            MyStringArray strarr = new MyStringArray("This","is","a","test.");

            strarr.Add("You");

            strarr.Add("are");

            strarr.Add("Welcome");

            strarr[2] = "another";

            foreach(string s in strarr)

            {

                Console.WriteLine("{0}",s);

            }

        }

    }

       当断点跟踪到foreach的时候再往下跟踪,就不太明白了。首先程序读取strarr对象的时候进入了MyStringArray. GetEnumerator方法,然后获取到一个MyStringArrayEnumerator对象,然后,光标又到了foreach关键字上,接着进入了MyStringArrayEnumerator. MoveNext方法中,从这个方法跳出后,跟踪点有移到了string s in上,然后又跟踪到了MyStringArrayEnumerator. Current属性中,然后又回到string s in能得莫名其妙的。

当时,我说了一句者可能是IEnumerable接口的内部机制(我这个概念错误应该是很严重的,接口中不可能调用这些方法)。那是为什么跟踪的结果会这样。我试图改造循环显示的部分,用for循环,但是发现strarr对象没有类似CountLength的属性。

查看MSDN上对foreach使用的解释:

 foreach (type identifier in expression) statement

其中:

type

identifier 的类型。

identifier

表示集合元素的迭代变量。如果迭代变量为值类型,则无法修改的只读变量也是有效的。

expression

对象集合或数组表达式。集合元素的类型必须可以转换为 identifier 类型。请不要使用计算为 null 的表达式。

而应计算为实现 IEnumerable 的类型或声明 GetEnumerator 方法的类型。在后一种情况中,GetEnumerator 应该要么返回实现 IEnumerator 的类型,要么声明 IEnumerator 中定义的所有方法。

statement

要执行的嵌入语句。

    实际上,应该是foreach调用GetEnumerator方法,这个方法要返回一个IEnumerator对象。foreach应该是利用这个IEnumerator对象中方法实现的简单的便利。后来,试验了一下MyStringArray类不继承IEnumerable接口,但是实现了GetEnumerator方法,结果是一样的

posted @ 2006-07-27 17:53  KiddLee  Views(3777)  Comments(8Edit  收藏  举报