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