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用于解决方案。