--------------------------------------------------------------------------------------------------------------------
如果你正在创建一个表现和行为都类似于集合的类(自定义ListBox类),允许类的用户使用foreach语句对类似集合的类中的成员进行枚举将会是很方便的。那么真对一个类似于集合的类,我们应该怎么使用foreach 语句呢?
想要使用foreach语句,必须实现IEnumerable 接口。
这个接口只要求实现一个方法: GetEnumerator。这个方法必须返回一个实现了IEnumerator 接口的对象(注意: IEnumerable 和 IEnumerator 是不同的接口,请不要搞混了)。除此以外,我们需要返回的这个对象不仅实现了IEnumerator,而且知道如何枚举ListBox对象。
因此,实现IEnumerator接口的最好办法是在实现IEnumerable的类里创建一个嵌套的IEnumerator类(ListBoxEnumerator类)。
namespace Test
{
public class ListBox:IEnumerable
{
private string[] strings;
private int ctr;
private int ctr0;
public string this[int x]
{
get
{
try
{
return strings[x];
}
catch (Exception ex)
{
return ex.ToString();
}
}
}
private class myListBoxEnumerator : IEnumerator
{
private ListBox lbt;
private int index;
public myListBoxEnumerator(ListBox lbt)
{
this.lbt = lbt;
}
//实现IEnumerator接口
#region 实现IEnumerator接口
public object Current
{
get { return (lbt[index++]); }
}
public bool MoveNext()
{
//index;
if (index >= lbt.strings.Length)
{
return false;
}
else
{
return true;
}
}
public void Reset()
{
index = -1;
}
#endregion
}
//这个方法必须返回一个实现了IEnumerator 接口的对象
public IEnumerator GetEnumerator()
{
return new myListBoxEnumerator(this);
}
public ListBox(params string[] initialStrings)
{
strings = new String[8];
foreach (string s in initialStrings)
{
strings[ctr++] = s;
}
}
public void Add(string theString)
{
strings[ctr] = theString;
ctr++;
}
public int GetNumEntries()
{
return ctr;
}
}
class Program
{
static void Main(string[] args)
{
ListBox lbt = new ListBox("Hello", "World");
lbt.Add("Who");
lbt.Add("Is");
lbt.Add("John");
lbt.Add("Galt");
foreach (string s in lbt)
{
Console.WriteLine("Value: {0}", s);
}
Console.ReadLine();
}
}
}
C#2.0以后
1、用泛型解决了Current属性返回一个Object对象;2、不需要为每个类型实现你自己的IEnumerator,不需要创建嵌套类。
namespace Test
{
public class ListBox:IEnumerable<string>
{
private string[] strings;
private int ctr;
private int ctr0;
public string this[int x]
{
get
{
try
{
return strings[x];
}
catch (Exception ex)
{
return ex.ToString();
}
}
}
public ListBox(params string[] initialStrings)
{
strings = new String[8];
foreach (string s in initialStrings)
{
strings[ctr++] = s;
}
}
public void Add(string theString)
{
strings[ctr] = theString;
ctr++;
}
public int GetNumEntries()
{
return ctr;
}
//这个方法必须返回一个实现了IEnumerator 接口的对象
public IEnumerator<string> GetEnumerator()
{
while (ctr0 < this.strings.Length)
{
yield return this[ctr0++];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
ListBox lbt = new ListBox("Hello", "World");
lbt.Add("Who");
lbt.Add("Is");
lbt.Add("John");
lbt.Add("Galt");
foreach (string s in lbt)
{
Console.WriteLine("Value: {0}", s);
}
Console.ReadLine();
}
}
}
yield语句。
yield return <expression>;
yield break;
您使用 yield return 语句每一次返回每个元素。
将使用 foreach 语句从客户端代码中调用迭代器。 foreach 循环的每次迭代都会调用迭代器方法。 迭代器方法运行到 yield return 语句时,会返回一个expression表达式并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。
您可以用 yield break语句来终止迭代。