为什么在MSDN的此示例中,在GetEnumerator
方法中,PeopleEnum
会返回IEnumerator
?
public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}
public string firstName;
public string lastName;
}
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];
}
}
//why???
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator) GetEnumerator();
}
public PeopleEnum GetEnumerator()
{
return new PeopleEnum(_people);
}
}
public class PeopleEnum : IEnumerator
{
public Person[] _people;
// Enumerators are positioned before the first element
// until the first MoveNext() call.
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
{
get
{
return Current;
}
}
public Person Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
更新 顺便说一句,如果Array数据类型实现ICloneable接口,为什么msdn通过编写for循环将pArray复制到_people?
答案 0 :(得分:3)
需要返回完全 IEnumerator
才能正确实现IEnumerable
接口。它是使用“显式接口实现”执行此操作的,因此在公共 API上,您看到PeopleEnum
,但IEnumerable
仍然很满意
但实际上你很少很少在C#2.0或更高版本中以这种方式写一个枚举器;你会使用迭代器块(yield return
)。见C# in Depth第6章(免费章节!)。
有关信息,PeopleEnum
在中存在的原因是这看起来像.NET 1.1示例,这是创建类型化枚举器的唯一方法。在.NET 2.0及更高版本中,IEnumerable<T>
/ IEnumerator<T>
有一个类型(通过泛型).Current
。
在.NET 2.0 / C#2.0(或更高版本)中,我只想:
public class People : IEnumerable<Person> {
/* snip */
public IEnumerator<Person> GetEnumerator() {
return ((IEnumerable<Person>)_people).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() { return _people.GetEnumerator();}
}
答案 1 :(得分:2)
实现IEnumerable的类型需要一个名为GetEnumerator的方法来返回一个IEnumerator。在该示例中(从C#2.0开始已经过时),有一个实现IEnumerator的枚举器类PeopleEnum。它是C#foreach语句在内部使用的内容。
更新的示例看起来更像是以下内容。请注意,现在C#支持迭代器不再需要PeopleEnum类。有效地,编译器会为您完成所有繁重的工作。
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];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
for (int i=0; i < _people.Length; i++) {
yield return _people[i];
}
}
}