相关文章推荐
文雅的炒饭  ·  jsonarrayattribute ...·  10 月前    · 
善良的牛腩  ·  获取当前时间 ...·  1 年前    · 
失望的跑步鞋  ·  Microsoft SQL Server ...·  1 年前    · 
有胆有识的勺子  ·  microsoft .NET ...·  1 年前    · 

阅读《c# in depth》的过程中,发现自己c#语言基础不够扎实,决定快速阅读一下《c#图解教程》。最近读到第19章学习泛型接口时,原本打算写一个简单的例子,结果搞了半天才成功。

我想很多读者,尤其是C#初学者也会有这个困扰,把这个我写的简单例子给大家分享一下吧。

class ColorsTemplateEnumerator<T>: IEnumerator<T> T[] colorsList; int position = -1; public ColorsTemplateEnumerator(T[] list) colorsList = list; public T Current if (position < 0 || position >= colorsList.Length) throw new InvalidOperationException(); return colorsList[this.position]; object IEnumerator.Current => throw new NotImplementedException(); public void Reset() this.position = -1; public bool MoveNext() if (this.position >= colorsList.Length - 1) return false; this.position++; return true; void IDisposable.Dispose() //throw new NotImplementedException(); class ColorsTemplate<T>:IEnumerable<T> T[] colorsList; public ColorsTemplate(T[] elem) colorsList = elem; IEnumerator<T> IEnumerable<T>.GetEnumerator() return new ColorsTemplateEnumerator<T>(colorsList); //throw new NotImplementedException(); IEnumerator IEnumerable.GetEnumerator() throw new NotImplementedException();

为了方便对比,把对应的非泛型写法也放在这里(与书中例子基本一致):

    class MyColorsEnumerator: IEnumerator
        string[] colors;
        int position = -1;
        public MyColorsEnumerator(MyColors mc)
            colors = mc.colors;
        public object Current
                if (this.position < 0 || this.position > colors.Length)
                    throw new InvalidOperationException();
                    return colors[this.position];
        public bool MoveNext()
            if (this.position < colors.Length - 1)
                this.position++;
                return true;
                return false;
        public void Reset()
            //Console.WriteLine("class MyColorsEnumerator: IEnumerator, Reset()");
            this.position = -1;
    class MyColors : IEnumerable
        public string[] colors;
        public MyColors(string[] colorList)
            this.colors = colorList;
        public MyColors()
            this.colors = new string[3];
            this.colors[0] = "Red";
            this.colors[1] = "Green";
            this.colors[2] = "Yellow";
        public IEnumerator GetEnumerator()
            return new MyColorsEnumerator(this);

最后给出一个main函数:

    class Program
        static void Main(string[] args)
            string[] colors = { "red", "violet", "yellow", "blue" };
            MyColors testCase = new MyColors(colors);
            foreach(var color in testCase)
                Console.WriteLine("get enumerator in Mycolors-testCase:" + Convert.ToString(color));
            ColorsTemplate<string> case2 = new ColorsTemplate<string>(colors);
            foreach(var color in case2)
                Console.WriteLine("get enumerator in ColorsTemplate<T>: " + Convert.ToString(color));

其实也不太难,书中图19.4已经表示了,在实现IEnumerator<T>接口时,除了需要实现Current、Reset、MoveNext,还要实现IEnumerator.Current与IDisposable.Dispos()。类似的,在实现IEnumerable<T>接口时,需要实现的是IEnumerable<T>.GetEnumerator()与IEnumerable.GetEnumerator()。

如果大家有什么问题或者对这一节有好的理解,欢迎评论区提出。

阅读《c# in depth》的过程中,发现自己c#语言基础不够扎实,决定快速阅读一下《c#图解教程》。最近读到第19章学习泛型接口时,原本打算写一个简单的例子,结果搞了半天才成功。我想很多读者,尤其是C#初学者也会有这个困扰,把这个我写的简单例子给大家分享一下吧。 class ColorsTemplateEnumerator&lt;T&gt;: IEnumerator&lt;T&gt; { T[] colorsList; int position IEnumerable 它利用 GetEnumerator() 返回 IEnumerator 集合访问器,声明实现该接口的class是“可枚举(enumerable)”的 通俗点说就是可进行迭代操作的类型。 IEnumerator解释:它是一个的集合访问器,使用foreach语句遍历集合或数组时,就是调用 Current、MoveNext()的结果。 今天给大家讲讲迭代器的 foreach极大简化了需要编写的代码,但是foreach只能在特定情况下使用-只能遍历可枚举集合. 什么是可枚举集合?就是实现了System.Collections.IEnumerable接口的集合 可以看到IEnumerable接口包含了一个名为GetEnumerator的方法: GetEnumerator返回IEnumerator 也就是返回了...