C#-实现IEnumerable接口时为什么要实现两个版本的Current?

C#-实现IEnumerable接口时为什么要实现两个版本的Current?,c#,C#,我假设下面的示例给出了在实现IEnumerable接口时应该遵循的最佳实践 问题是: 为什么我们要提供两种版本的当前方法 何时使用版本1(对象IEnumerator.Current) 何时使用第二版(当前公众人物) 如何在foreach语句中使用PeopleEnum。//更新 公共类PeopleEnum:IEnumerator { 公众人士【】人; //枚举数位于第一个元素之前 //直到第一次调用MoveNext()为止。 int位置=-1; 公众人数(人[]名单) { _人员=列表; } 公

我假设下面的示例给出了在实现IEnumerable接口时应该遵循的最佳实践

问题是:

  • 为什么我们要提供两种版本的当前方法
  • 何时使用版本1(对象IEnumerator.Current)
  • 何时使用第二版(当前公众人物)
  • 如何在foreach语句中使用PeopleEnum。//更新
  • 公共类PeopleEnum:IEnumerator
    {
    公众人士【】人;
    //枚举数位于第一个元素之前
    //直到第一次调用MoveNext()为止。
    int位置=-1;
    公众人数(人[]名单)
    {
    _人员=列表;
    }
    公共图书馆
    {
    位置++;
    返回(位置<_人.长度);
    }
    公共无效重置()
    {
    位置=-1;
    }
    //显式接口实现
    对象IEnumerator.Current///**版本一**
    {
    得到
    {
    回流;
    }
    }
    公众人士当前版本//**第二版**
    {
    得到
    {
    尝试
    {
    返回人员[位置];
    }
    捕获(IndexOutOfRangeException)
    {
    抛出新的InvalidOperationException();
    }
    }
    }
    }
    
    IEnumerator.Current是一个显式接口实现

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

    您将看到它返回
    对象
    ,并实际使用另一个返回
    的实现


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

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

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

    但是你需要做的唯一一件事就是实现这个接口,如果你愿意,你可以隐式地实现它,但是这有什么原因吗?如果我想在课堂上使用MovePrevious?如果我将对象投射(解开)到人身上会很酷吗


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

    我怀疑原因是此代码示例源自实现
    IEnumerator
    的示例类-如果示例类
    PeopleEnum
    实现
    IEnumerator
    ,则此方法将是必需:
    IEnumerator
    继承
    IEnumerator
    ,因此在实现
    IEnumerator
    时必须同时实现这两个接口


    非泛型的
    IEnumerator
    的实现需要
    Current
    返回对象-另一方面,强类型的
    IEnumerator
    需要Current返回类型为
    T
    的实例-使用显式和直接的接口实现是实现这两者的唯一方法要求。

    不再需要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<Person>
    {
        public Person[] _people;
    
        public PeopleEnum(Person[] list)
        {
            _people = list;
        }
    
        public IEnumerator<Person> GetEnumerator()
        {
            foreach (Person person in _people)
                yield return person;
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    
    公共类PeopleEnum:IEnumerable
    {
    公众人士【】人;
    公众人数(人[]名单)
    {
    _人员=列表;
    }
    公共IEnumerator GetEnumerator()
    {
    foreach(人中人)
    收益人;
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
    返回GetEnumerator();
    }
    }
    
    尽管所有这些都是正确的,但您的推断是,对IEnumerator的转换很少;事实并非如此。IEnumerable需要一个GetEnumerator()方法,该方法返回IEnumerator类型的对象。反过来,几乎所有使用IEnumerables的内置代码都会使用GetEnumerator(),例如foreach和大多数Linq。我刚刚发现,您实际上给出了我需要的答案。--非常感谢。
    public class PeopleEnum : IEnumerable<Person>
    {
        public Person[] _people;
    
        public PeopleEnum(Person[] list)
        {
            _people = list;
        }
    
        public IEnumerator<Person> GetEnumerator()
        {
            foreach (Person person in _people)
                yield return person;
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }