为什么在这个例子中(来自msdn),在GetEnumerator方法中,new PeopleEnum返回IEnumerator?
为什么在 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?
Why in this example from MSDN, in GetEnumerator
method, PeopleEnum
returns 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();
}
}
}
UPDATE:
BTW, if Array data type implements ICloneable interface, why msdn has copied pArray to _people by writing a for loop?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
实现 IEnumerable 的类型需要一个名为 GetEnumerator 的方法,该方法返回 IEnumerator。在该示例中(从 C# 2.0 开始已经过时),有一个实现 IEnumerator 的枚举器类 PeopleEnum。这是 C# foreach 语句在内部使用的内容。
更新的示例如下所示。请注意,既然 C# 支持迭代器,就不再需要 PeopleEnum 类。实际上,编译器会为您完成所有繁重的工作。
Types implementing IEnumerable require a method called GetEnumerator that returns an IEnumerator. In that example (which is pretty obsolete as of C# 2.0) there is an enumerator class PeopleEnum that implements IEnumerator. It's what's used internally by the C# foreach statement.
A more up to date example would look more like the following. Note there's no longer a need for a PeopleEnum class now that C# supports iterators. Effectively the compiler does all the heavy lifting for you.
它需要准确返回
IEnumerator
才能正确实现IEnumerable
接口。它使用“显式接口实现”来执行此操作,因此在 public API 上您会看到PeopleEnum
,但IEnumerable
仍然很高兴但实际上在 C# 2.0 或更高版本中,您很少会以这种方式编写枚举器;您将使用迭代器块(
yield return
)。请参阅深入了解 C# 第 6 章(免费章节!)。作为信息,
PeopleEnum
存在的原因根本是因为它看起来像 .NET 1.1 示例,这是创建类型化枚举器的唯一方法。在 .NET 2.0 及更高版本中,有IEnumerable
/IEnumerator
,它具有类型化(通过泛型).Current
。在 .NET 2.0 / C# 2.0 (或更高版本)中,我会简单地:
It needs to return exactly
IEnumerator
to properly implement theIEnumerable
interface. It is doing this using an "explicit interface implementation", so on the public API you seePeopleEnum
, butIEnumerable
is still happyBut in reality you would very rarely write an enumerator this way in C# 2.0 or above; you'd use an iterator block (
yield return
). See C# in Depth chapter 6 (free chapter!).For info, the reason that
PeopleEnum
exists at all here is that this looks like a .NET 1.1 sample, where that is the only way to create a typed enumerator. In .NET 2.0 and above there isIEnumerable<T>
/IEnumerator<T>
, which has a typed (via generics).Current
.In .NET 2.0 / C# 2.0 (or above) I would have simply: