IEnumerable和IEnumerator详解
程序员文章站
2023-11-15 16:57:46
IEnumerable是可枚举的所有非泛型集合的基接口, IEnumerable包含一个方法GetEnumerator(),该方法返回一个IEnumerator;IEnumerator提供通过Current属性以及MoveNext()和Reset()方法来循环访问集合的功能。 ...
支持对非泛型集合的简单迭代。接口源码如下:
public interface ienumerator
{
[__dynamicallyinvokable]
bool movenext();
[__dynamicallyinvokable]
object current { [__dynamicallyinvokable] get; }
[__dynamicallyinvokable]
void reset();
}
举例说明
示例演示了通过实现ienumerable和ienumerator接口来循环访问自定义集合的最佳实践。
定义一个简单的实体类:
public class person
{
public person(string name, int age)
{
this.name = name;
this.age = age;
}
public string name;
public int age;
}
定义一个实体类的集合,继承ienumerate:
public class people : ienumerable
{
private person[] _people;
public people(person[] parray)
{
_people = new person[parray.length];
for (int i = 0; i < parray.length; i++)
{
_people[i] = parray[i];
}
}
///
/// getenumerator方法的实现
///
///
ienumerator ienumerable.getenumerator()
{
return getenumerator();
}
public peopleenum getenumerator()
{
return new peopleenum(_people);
}
}
定义一个枚举器,继承ienumerator:
public class peopleenum : ienumerator
{
public person[] _people;
///
/// 枚举器位于第一个元素之前直到第一个movenext()调用。
///
private int position = -1;
public peopleenum(person[] list)
{
_people = list;
}
public bool movenext()
{
position++;
return position < _people.length;
}
public void reset()
{
position = -1;
}
object ienumerator.current => current;
public person current
{
get
{
try
{
return _people[position];
}
catch (indexoutofrangeexception)
{
throw new invalidoperationexception();
}
}
}
}
具体调用:
person[] peoplearray = new person[3]
{
new person("张三", 15),
new person("李四", 18),
new person("王五", 21),
};
people peoplelist = new people(peoplearray);
foreach (person p in peoplelist)
console.writeline(p.name + "\t" + p.age);
输出:
其中,上边调用中foreach等价于
ienumerator enumeratorsimple = peoplelist.getenumerator();
while (enumeratorsimple.movenext())
{
person p = enumeratorsimple.current as person;
console.writeline(p?.name + "\t" + p?.age);
}
通过例子,可以得出:
实现一个自定义集合,继承于ienumerate,必须实现一个枚举器;
c# 语言的foreach语句隐藏了枚举数的复杂性,因此, 建议foreach使用, 而不是直接操作枚举器;
枚举器可用于读取集合中的数据,但不能用于修改基础集合。
总结
ienumerable代表继承此接口的类(比如arraylist,ilist,list等)可以获取一个ienumerator来实现枚举这个类中包含的集合中的元素的功能,是 .net framework 中最基本的集合访问器。在编程中,lambda表达式通过select()或者where()返回的变量为ienumerate,此时我们可以通过foreach遍历。希望本文对你有所帮助,下一篇介绍lambda中的select和where,感兴趣的朋友可以加关注,欢迎留言交流!...
引言
ienumerable是可枚举的所有非泛型集合的基接口, ienumerable包含一个方法getenumerator(),该方法返回一个ienumerator;ienumerator提供通过current属性以及movenext()和reset()方法来循环访问集合的功能。
ienumerable 接口
公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。接口源码如下:
public interface ienumerable { [dispid(-4), __dynamicallyinvokable] ienumerator getenumerator(); }
ienumerator 接口
支持对非泛型集合的简单迭代。接口源码如下:
public interface ienumerator { [__dynamicallyinvokable] bool movenext(); [__dynamicallyinvokable] object current { [__dynamicallyinvokable] get; } [__dynamicallyinvokable] void reset(); }
举例说明
示例演示了通过实现ienumerable和ienumerator接口来循环访问自定义集合的最佳实践。
定义一个简单的实体类:
public class person { public person(string name, int age) { this.name = name; this.age = age; } public string name; public int age; }
定义一个实体类的集合,继承ienumerate:
public class people : ienumerable { private person[] _people; public people(person[] parray) { _people = new person[parray.length]; for (int i = 0; i < parray.length; i++) { _people[i] = parray[i]; } } /// <summary> /// getenumerator方法的实现 /// </summary> /// <returns></returns> ienumerator ienumerable.getenumerator() { return getenumerator(); } public peopleenum getenumerator() { return new peopleenum(_people); } }
定义一个枚举器,继承ienumerator:
public class peopleenum : ienumerator { public person[] _people; /// <summary> /// 枚举器位于第一个元素之前直到第一个movenext()调用。 /// </summary> private int position = -1; public peopleenum(person[] list) { _people = list; } public bool movenext() { position++; return position < _people.length; } public void reset() { position = -1; } object ienumerator.current => current; public person current { get { try { return _people[position]; } catch (indexoutofrangeexception) { throw new invalidoperationexception(); } } } }
具体调用:
person[] peoplearray = new person[3] { new person("张三", 15), new person("李四", 18), new person("王五", 21), }; people peoplelist = new people(peoplearray); foreach (person p in peoplelist) console.writeline(p.name + "\t" + p.age);
输出:
其中,上边调用中foreach等价于
ienumerator enumeratorsimple = peoplelist.getenumerator(); while (enumeratorsimple.movenext()) { person p = enumeratorsimple.current as person; console.writeline(p?.name + "\t" + p?.age); }
通过例子,可以得出:
- 实现一个自定义集合,继承于ienumerate,必须实现一个枚举器;
- c# 语言的foreach语句隐藏了枚举数的复杂性,因此, 建议foreach使用, 而不是直接操作枚举器;
- 枚举器可用于读取集合中的数据,但不能用于修改基础集合。
总结
ienumerable代表继承此接口的类(比如arraylist,ilist,list<t>等)可以获取一个ienumerator来实现枚举这个类中包含的集合中的元素的功能,是 .net framework 中最基本的集合访问器。在编程中,lambda表达式通过select()或者where()返回的变量为ienumerate<t>,此时我们可以通过foreach遍历。希望本文对你有所帮助,下一篇介绍lambda中的select和where,感兴趣的朋友可以加关注,欢迎留言交流!
上一篇: .net反编译原理
下一篇: 《吊打面试官》系列-Redis基础