假设我有一个员工实例列表,employeeList
IEnumerator enumerator = employeeList.GetEnumerator();
while (enumerator.MoveNext())
{
Console.Write(enumerator.Current + " ");
}
Run Code Online (Sandbox Code Playgroud)
我有三个问题:
关于枚举器如何工作,我有一个很好的想法,就像C++中的迭代器一样.但是我不理解MoveNex方法(比如C++中的itr ++),因为它首先检查条件(是否在最后一个元素中),让我们说如果我们使用enumerator.Current来访问第一个元素,我认为它实际上当调用MoveNext()时,已经"移动"到列表中的下一个元素,因此当前指向的对象实际上是列表中的第二个元素?
我认为在使用enumerator.Current时我们可以访问当前元素是有意义的,例如,我们应该能够使用
enumerator.Current.name
就像我们可以在C++中使用(*itr).name或itr => name一样,但C#看起来并没有实现这种功能,那么使用enumerator.Current有什么意义呢?
IEnumerable<int> result = GetData() ?? Enumerable.Empty<int>;
作为C#的初学者,我只知道&&,||运营商,什么是" ??"?
Tim*_*ter 23
阅读文档:"在创建枚举数之后,枚举数位于集合中的第一个元素之前,第一个调用MoveNext 将枚举数提升到集合的第一个元素 "
代码的问题在于您将枚举数分配给非泛型枚举变量.这是有效的,因为通用IEnumerator<T>接口继承自非泛型.但这也是你不能使用Employee-class 属性的原因,因为类型是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; // ...
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用var哪个像C#中的实际类型的占位符一样工作:
using(var empEnumerator = employeeList.GetEnumerator())
{ ... }
Run Code Online (Sandbox Code Playgroud)
如果您只需要枚举整个集合,那就foreach更舒服了:
foreach(Employee emp in employeeList)
{
Console.WriteLine(emp.Name);
}
Run Code Online (Sandbox Code Playgroud)
最初,枚举数位于第一个元素之前(因为枚举可能为空).因此,第一次调用MoveNext将其移动到第一个元素(如果枚举为空,则返回false).
您正在使用旧的非泛型版本IEnumerator,其中Current返回一个object.您可以将对象强制转换为具体类型并调用.name,或者更好地使用employeeList返回强类型IEnumerator<Employee>(例如List<Employee>)的类型.
这是空合并运算符.
PS:将来,请为每个问题创建一个SO问题.1 + 2可以看作是相关的,但3肯定不是.
PPS:如果您只想要一个以空格分隔的员工姓名列表,则根本不需要显式循环:
var names = String.Join(" ", employeeList.Select(e => e.name));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19313 次 |
| 最近记录: |