.Net学习难点讨论系列11 - foreach与迭代器
来源:互联网 发布:走地分析软件 编辑:程序博客网 时间:2024/05/16 10:35
(本文主要整理于ASP.NET2.0开发指南部分内容)
在.NET 1.1中要使一个自定义的集合类可以与foreach一起工作,我们需要实现IEnumerable接口的GetEnumerator方法。该数据集合中的元素需要实现IEnumerator接口。我们直接看下面这个例子:
public class Persons : IEnumerable
{
public string[] m_Names;
public Persons(params string[] Names)
{
m_Names = new string[Names.Length];
Names.CopyTo(m_Names, 0);
}
//实现索引器
public string this[int index]
{
get
{
return m_Names[index];
}
set
{
m_Names[index] = value;
}
}
//实现IEnumerable成员
//需返回一个IEnumerator类型的对象
#region IEnumerable 成员
IEnumerator IEnumerable.GetEnumerator()
{
return new PersonsEnumerator(this);
}
#endregion
}
public class PersonsEnumerator : IEnumerator
{
int index = -1;
Persons P;
public PersonsEnumerator(Persons P)
{
this.P = P;
}
#region IEnumerator 成员
object IEnumerator.Current
{
get
{
return P.m_Names[index];
}
}
bool IEnumerator.MoveNext()
{
int tempIndex = ++index;
if (tempIndex >= P.m_Names.Length)
{
return false;
}
else
{
return true;
}
}
void IEnumerator.Reset()
{
index = -1;
}
#endregion
}
使用(非泛型)迭代器的方式:
static void Main()
{
Persons arrPersons = new Persons("Michel", "Rebecca", "Polaris");
foreach (string s in arrPersons)
{
Console.WriteLine(s);
}
}
在C# 2.0中我们可以通过新增的关键字 – yeild,来方便的实现一个迭代器。而且.NET2.0中新增的泛型可以使迭代器强类型化。
一步步进行:首先我们将上述程序改写为用yield关键字实现(仍然是非泛型)。
public class Persons : IEnumerable
{
public string[] m_Names;
public Persons(params string[] Names)
{
m_Names = new string[Names.Length];
Names.CopyTo(m_Names, 0);
}
#region IEnumerable 成员
IEnumerator IEnumerable.GetEnumerator()
{
for (int i = 0; i < m_Names.Length; i++)
{
yield return m_Names[i];
}
}
#endregion
}
接下来,我们将此方法改写为泛型的实现:
public class Persons<T> : IEnumerable<T>
{
public T[] m_Names;
public Persons(params T[] Names)
{
m_Names = new T[Names.Length];
Names.CopyTo(m_Names, 0);
}
#region IEnumerable<T> 成员
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
for (int i = 0; i < m_Names.Length; i++)
{
yield return m_Names[i];
}
}
#endregion
}
泛型版迭代器的使用:
static void Main()
{
Persons<string> arrPersons = new Persons<string>("Michel", "Rebecca", "Polaris");
foreach (string s in arrPersons)
{
Console.WriteLine(s);
}
}
上文基本列出了怎样使用yield实现一个迭代器。
下面来说一下yield的一些使用方式:
1. 终止yield迭代的方式
IEnumerator IEnumerable.GetEnumerator()
{
for (int i = 0; i < m_Names.Length; i++)
{
yield return m_Names[i];
if (i >= 1)
{
yield break;
}
}
}
2. 逆序迭代内容
IEnumerator IEnumerable.GetEnumerator()
{
for (int i = (m_Names.Length - 1); i >= 0; --i)
{
yield return m_Names[i];
}
}
3. 迭代器的另一种实现,返回实现IEnumerable<T>接口的对象,不实现GetEnumerator()方法。
public class Persons<T>
{
private T[] m_Names;
public Persons(params T[] Names)
{
m_Names = new T[Names.Length];
Names.CopyTo(m_Names, 0);
}
public IEnumerable<T> GetPersons()
{
for (int i = 0; i < m_Names.Length; i++)
{
yield return m_Names[i];
}
}
}
class Program
{
static void Main()
{
Persons<string> arrPersons = new Persons<string>("Michel", "Rebecca", "Polaris");
foreach (string s in arrPersons.GetPersons())
{
Console.WriteLine(s);
}
}
}
- .Net学习难点讨论系列11 - foreach与迭代器
- .Net学习难点讨论系列17
- .Net学习难点讨论系列17
- .Net学习难点讨论系列4 – .Net委托类型
- .Net学习难点讨论系列7 - .NET委托补充
- .Net学习难点讨论系列1 – 委托与事件之事件
- .Net学习难点讨论系列2 – 细说C#中new关键字与多态
- .Net学习难点讨论系列1 – 委托与事件之事件
- .Net学习难点讨论系列6 - .Net中对字符串处理的方法
- .Net学习难点讨论系列6 - .Net中对字符串处理的方法
- .Net学习难点讨论系列3 – .线程同步问题之一
- .Net学习难点讨论系列5 – 线程同步问题之二
- .Net学习难点讨论系列8 - 泛型字典类比较
- .Net学习难点讨论系列9 -泛型类型参数的约束 泛型方法
- .Net学习难点讨论系列10 - 匿名方法,Lambda表达式及其对局部变量的影响
- 讨论Java与。net
- Linux内核驱动学习难点与学习方法
- foreach与&引用的学习
- 三道很经典的面试题目
- .Net学习难点讨论系列10 - 匿名方法,Lambda表达式及其对局部变量的影响
- 话说VCARD
- 一款Android精品休闲益智类游戏《荷塘与蛙》给力发布!
- Android 的 联系人导入和导出方案探讨
- .Net学习难点讨论系列11 - foreach与迭代器
- Android中使用VCard
- SQL语句大全 (转)
- android 使用vcard示例
- 对照ArcGIS坐标系统文件(.prj)用Deskpro完成投影转换
- .NET 面试题 - 初级&中级
- VCard(.VCF) 2.1(rfc-2426)标准通信薄基本格式
- Ext grid 如何控制滚动条
- .Net面试题 - 高级