C# 在迭代器列表linq上迭代

C# 在迭代器列表linq上迭代,c#,linq,iterator,C#,Linq,Iterator,列表枚举器在放入列表时不起作用。例如,如果有两个列表(两个枚举数) 公共无效测试() { var firstList=newlist(){1,2,3}; var secondList=newlist(){4,5,6}; var List=新列表(); 列表。添加(第一个列表); 列表。添加(第二个列表); //不起作用 var iterators=lists.Select(x=>x.GetEnumerator()).ToList(); 迭代器.ForEach(x=>x.MoveNext());

列表枚举器在放入列表时不起作用。例如,如果有两个列表(两个枚举数)

公共无效测试()
{
var firstList=newlist(){1,2,3};
var secondList=newlist(){4,5,6};
var List=新列表();
列表。添加(第一个列表);
列表。添加(第二个列表);
//不起作用
var iterators=lists.Select(x=>x.GetEnumerator()).ToList();
迭代器.ForEach(x=>x.MoveNext());
迭代器.ForEach(x=>Console.WriteLine(x.Current));
//工作
var firstIterator=迭代器[0];
var secondIterator=迭代器[1];
firstIterator.MoveNext();secondIterator.MoveNext();
Console.WriteLine(firstIterator.Current);
Console.WriteLine(secondIterator.Current);
}
第一部分不工作并打印
0 0
,而第二部分工作并打印
1 4


我不明白第一部分的错误是什么,以及如何解决它。

这是因为您在非工作部分运行了两个独立的
.ForEach()
。在1 foreach中执行这两个操作(
MoveNext()
,然后打印)<代码>移动下一步将不会在
.Foreach()
中被记住,以便更好地解释:

这个:

iterators.ForEach(x => x.MoveNext());
iterators.ForEach(x => Console.WriteLine(x.Current));
iterators.ForEach(x => { x.MoveNext(); Console.WriteLine(x.Current); });
变成:

iterators.ForEach(x => x.MoveNext());
iterators.ForEach(x => Console.WriteLine(x.Current));
iterators.ForEach(x => { x.MoveNext(); Console.WriteLine(x.Current); });

这是因为您在非工作部件中运行了两个独立的
.ForEach()
。在1 foreach中执行这两个操作(
MoveNext()
,然后打印)<代码>移动下一步将不会在
.Foreach()
中被记住,以便更好地解释:

这个:

iterators.ForEach(x => x.MoveNext());
iterators.ForEach(x => Console.WriteLine(x.Current));
iterators.ForEach(x => { x.MoveNext(); Console.WriteLine(x.Current); });
变成:

iterators.ForEach(x => x.MoveNext());
iterators.ForEach(x => Console.WriteLine(x.Current));
iterators.ForEach(x => { x.MoveNext(); Console.WriteLine(x.Current); });

列表的枚举数实现为值类型():

这意味着-当您将迭代器传递给方法时,迭代器将按值传递(即传递迭代器的副本,而不是传递对迭代器实例的引用)
ForEach
方法只是在循环中执行操作:

iterators.ForEach(copy => copy.MoveNext());
Action委托是一个方法,因此您要将每个迭代器的副本传递给该方法。所以原始迭代器保持不变。当您第二次调用
ForEach
时,原始未触及迭代器的副本也会传递到那里:

iterators.ForEach(newCopy => Console.WriteLine(newCopy.Current));
但是原始迭代器处于初始状态(在第一项之前),这就是为什么在读取
Current
value时会看到integer类型的默认值

您可以使用迭代器的单个副本:

iterators.ForEach(copy => { copy.MoveNext(); Console.WriteLine(copy.Current); });
或框值类型以通过引用传递(请注意,
迭代器的类型将更改):

var迭代器=列表。选择(x=>(IEnumerable)x.GetEnumerator()).ToList();

列表的枚举器实现为值类型():

这意味着-当您将迭代器传递给方法时,迭代器将按值传递(即传递迭代器的副本,而不是传递对迭代器实例的引用)
ForEach
方法只是在循环中执行操作:

iterators.ForEach(copy => copy.MoveNext());
Action委托是一个方法,因此您要将每个迭代器的副本传递给该方法。所以原始迭代器保持不变。当您第二次调用
ForEach
时,原始未触及迭代器的副本也会传递到那里:

iterators.ForEach(newCopy => Console.WriteLine(newCopy.Current));
但是原始迭代器处于初始状态(在第一项之前),这就是为什么在读取
Current
value时会看到integer类型的默认值

您可以使用迭代器的单个副本:

iterators.ForEach(copy => { copy.MoveNext(); Console.WriteLine(copy.Current); });
或框值类型以通过引用传递(请注意,
迭代器的类型将更改):

var迭代器=列表。选择(x=>(IEnumerable)x.GetEnumerator()).ToList();
这是因为该方法返回一个可变结构

当您将其分配给变量并调用
MoveNext
Current
时,它会工作。但当传递给委托时,它是按值传递的,因此委托会收到一个副本,因此调用
MoveNext
不会影响原始
结构
当前

这只是可变结构的一个副作用

如果你改变

x => x.GetEnumerator()

这两个代码段都可以工作,因为现在
迭代器将包含返回结构的盒式引用。

这是因为该方法返回可变结构

当您将其分配给变量并调用
MoveNext
Current
时,它会工作。但当传递给委托时,它是按值传递的,因此委托会收到一个副本,因此调用
MoveNext
不会影响原始
结构
当前

这只是可变结构的一个副作用

如果你改变

x => x.GetEnumerator()


这两个代码段都可以工作,因为现在
迭代器将包含返回结构的盒式引用。

是否特别需要使用迭代器?
x
迭代器[0]
不是相同的引用
x
是每个
ForEach
调用中的本地副本。是否特别需要使用迭代器?
x
迭代器[0]
不是相同的引用
x
是每个
ForEach
调用中的本地副本。它没有解释为什么在第一次ForEachI需要移动和使用迭代器后迭代器仍处于默认状态。另外,如果我使用迭代器[0]
MoveNext()
然后在下一行
迭代器[0]。Current
也将不起作用。@Petar可能会指定吗?现在就找你找一个更好的solution@PetarIvan有一个解决方案,它没有解释为什么在第一次ForEachI需要移动和使用迭代器后迭代器仍处于默认状态。另外,如果我使用迭代器[0]
MoveNext()
然后在下一行
迭代器[0]。Current
也将不起作用。@Petar可能会指定吗?现在就找你找一个更好的solution@PetarIvan有一个解决方案两个选项都是wokring。Tnx用于解决方案。两个选项都是wokring。Tnx用于解决方案。