阅读《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<T>: IEnumerator<T> { T[] colorsList; int position
IEnumerable 它利用 GetEnumerator() 返回 IEnumerator 集合访问器,声明实现该接口的class是“可枚举(enumerable)”的 通俗点说就是可进行迭代操作的类型。
IEnumerator解释:它是一个的集合访问器,使用foreach语句遍历集合或数组时,就是调用 Current、MoveNext()的结果。
今天给大家讲讲迭代器的
foreach极大简化了需要编写的代码,但是foreach只能在特定情况下使用-只能遍历可枚举集合.
什么是可枚举集合?就是实现了System.Collections.IEnumerable接口的集合
可以看到IEnumerable接口包含了一个名为GetEnumerator的方法:
GetEnumerator返回IEnumerator
也就是返回了...