.net 使用IEnumerator循环访问列表

6tdlim6h  于 2022-11-19  发布在  .NET
关注(0)|答案(4)|浏览(133)

假设我有一个employee示例列表employeeList,我可以遍历它们,如下所示:

IEnumerator enumerator = employeeList.GetEnumerator();
while (enumerator.MoveNext())
{
    Console.Write(enumerator.Current + " ");
}

我有三个问题:
1.我对枚举器的工作原理有一个大致的了解,就像C中的迭代器一样。但是我不理解MoveNext()方法(就像C中的itr ++),因为该方法首先检查条件(它是否在最后一个元素中)。假设我们使用enumerator.Current访问第一个元素:我认为它实际上已经“移动”到了列表中的下一个元素,就像MoveNext()被调用一样,那么Current指向的对象不应该是列表中的第二个元素吗?
1.我认为在使用enumerator.Current时可以访问当前元素是有意义的。例如,我们应该可以使用enumerator.Current.name,就像我们可以在C++中使用(*itr).nameitr=>name一样。然而,C#看起来并没有实现这种功能。那么使用enumerator.Current的意义是什么呢?
1.这个问题与IEnumerator无关,我只是看到了这样的代码:
IEnumerable<int> result = GetData() ?? Enumerable.Empty<int>;
作为C#的初学者,我只知道&&||运算符。什么是??

ghg1uchk

ghg1uchk1#

读取documentation:* “创建枚举数后,该枚举数位于集合中的第一个元素之前,并且第一次调用MoveNext会将枚举数向前移动到集合的第一个元素”*
你的代码的问题是你把枚举数赋给了一个非泛型的枚举数变量。这是因为泛型的IEnumerator<T>接口继承自非泛型的。但这也是为什么你不能使用Employee类的属性的原因,因为类型是Object。你必须先把enumerator.Current转换成正确的类型。
因此,最好使用泛型版本(并使用using正确处理它):

using(IEnumerator<Employee> empEnumerator = employeeList.GetEnumerator())
{
    while(empEnumerator.MoveNext())
    {
        // now empEnumerator.Current is the Employee instance without casting
        Employee emp = empEnumerator.Current;
        string empName = emp.Name;  // ...
    }
}

您也可以使用var,其作用类似于C#中真实的类型的占位符:

using(var empEnumerator = employeeList.GetEnumerator())
{ ... }

如果你只需要枚举整个集合,那么foreach会更方便:

foreach(Employee emp in employeeList)
{
     Console.WriteLine(emp.Name);
}
nfg76nw0

nfg76nw02#

1.一开始,枚举数被放置在第一个元素的 * 之前 *(因为可枚举项可能是空的)。因此,第一次调用MoveNext时,它会移动到第一个元素(如果可枚举项是空的,则返回false)。
1.您使用的是IEnumerator的旧的非泛型版本,其中Current返回object。您可以将对象转换为具体类型并调用.name,或者更好的方法是使用employeeList的类型,该类型返回强类型IEnumerator<Employee>(如List<Employee>)。
1.这是null-coalescing operator
PS:以后请每个问题出一个SO问题,1+2可以看作是相关的,但3肯定不是。
PPS:如果只需要一个以空格分隔的雇员姓名列表,则根本不需要显式循环:

var names = String.Join(" ", employeeList.Select(e => e.name));
n6lpvg4x

n6lpvg4x3#

IEnumerable的使用方法如下:

foreach (var e in employeeList)
{
  Console.Write(e + " ");
}
webghufk

webghufk4#

IEnumerable Interface
公开枚举值,该枚举值支援在非泛型集合上进行简单反覆运算。

foreach (var employee in employeeList)
{
    // do your stuff  here, you have full employee object
   Console.WriteLine(employee.FirstName); 
}

c# null coalescing operator
??运算符被称为空合并运算符。如果操作数不为空,它返回左边的操作数;否则返回右边的操作数。

相关问题