C# – 为什么在实现IEnumberable接口时实现两个版本的Current?

我假设以下示例给出了我们在实现IEnumberable接口时应遵循的最佳实践。

http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.movenext.aspx

这是一个问题:

  1. 我们为什么要提供两种版本的Current方法?
  2. 当使用版本ONE(对象IEnumerator.Current)?
  3. 当使用版本TWO(公共人员当前)?
  4. 如何在foreach语句中使用PeopleEnum。 // 更新

谢谢

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; } // explicit interface implementation object IEnumerator.Current /// **version ONE** { get { return Current; } } public Person Current /// **version TWO** { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } 

我怀疑原因是这个代码示例是从实现IEnumerator的示例类PeopleEnum – 如果示例类PeopleEnum实现了IEnumerator这种方法: IEnumeratorinheritanceIEnumerator因此您必须实现这两个接口实现IEnumerator

非通用IEnumerator要求Current返回对象 – 另一方面强类型IEnumerator要求Current返回类型T的实例 – 使用显式和直接接口实现是满足这两个要求的唯一方法。

IEnumerator.Current是一个显式接口实现。

如果将迭代器强制转换为IEnumerator (这是框架对foreach ),则只能使用它。 在其他情况下,将使用第二个版本。

您将看到它返回object并实际使用返回Person的其他实现。

接口本身不需要第二个实现,但是为了方便而返回预期的类型而不是object

不再需要长forms实现IEnumerator:

 public class PeopleEnum : IEnumerable { public Person[] _people; public PeopleEnum(Person[] list) { _people = list; } public IEnumerator GetEnumerator() { foreach (Person person in _people) yield return person; } } 

并进一步将其带入21世纪,不要使用非通用的IEnumerable:

 public class PeopleEnum : IEnumerable { public Person[] _people; public PeopleEnum(Person[] list) { _people = list; } public IEnumerator GetEnumerator() { foreach (Person person in _people) yield return person; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 

它是为了方便,例如。 在while(p.MoveNext())循环中以类型安全的方式使用PeopleEnum.Current,而不是显式地执行foreach枚举。

但你唯一需要做的就是实现界面,如果你愿意,可以隐式地做,但是有没有理由呢? 如果我想在课堂上使用MovePrevious? 如果我将对象强制转换(取消包装)给Person会不会很酷?

如果您认为可以使用更多操作方法扩展类,那么Person Current是一件很酷的事情。

版本2不是界面的一部分。 您必须满足接口要求。