通过 linq 访问时,似乎重新创建了 Linq 枚举器列表
Linq list of enumerators seem to be recreated when accessed through linq
我试图了解以下代码段中出了什么问题。
var signals = new List<List<double>>
{
new List<double> {1, 2, 3},
new List<double> {2, 3, 4},
};
var enumerators = signals.Select(l => l.GetEnumerator()).ToList();
if (enumerators.All(enumerator => enumerator.MoveNext()))
{
var cummulative = enumerators.Sum(enumerator => enumerator.Current);
}
为什么两个枚举器都指向当前值 0?我希望两者都指向列表中的第一个数字,分别是 1 和 2。
每次我通过 linq 访问枚举器时,它似乎都会重新启动。为什么?
Initially, the enumerator is positioned before the first element in
the collection. At this position, the Current
property is undefined.
Therefore, you must call the MoveNext
method to advance the enumerator
to the first element of the collection before reading the value of
Current
.
要获得预期的行为并对值求和,您可以编写以下内容
var cumulative = 0d;
foreach (var enumerator in enumerators)
{
if (enumerator.MoveNext())
cumulative += enumerator.Current;
}
All
只是 return bool
值,它不会更改源序列或其项目。
Each time I access the enumerator via linq it seems to restart. Why?
Enumerator<T>
是 struct
和值类型,它不是 class。每次修改时,修改副本,源enumerators
列表中的元素保持不变,枚举器位于第一个元素
之前
按照以下更改您的代码
var enumerators = signals.Select(l => l.GetEnumerator() as IEnumerator<double>).ToList();
按照这个 SO post
It is because the enumerator of List is a struct whereas the enumerator of Array is a class.
So when you call Enumerable.All with the struct, copy of enumerator is made and passed as a parameter to Func since structs are copied by value. So e.MoveNext is called on the copy, not the original.
我试图了解以下代码段中出了什么问题。
var signals = new List<List<double>>
{
new List<double> {1, 2, 3},
new List<double> {2, 3, 4},
};
var enumerators = signals.Select(l => l.GetEnumerator()).ToList();
if (enumerators.All(enumerator => enumerator.MoveNext()))
{
var cummulative = enumerators.Sum(enumerator => enumerator.Current);
}
为什么两个枚举器都指向当前值 0?我希望两者都指向列表中的第一个数字,分别是 1 和 2。
每次我通过 linq 访问枚举器时,它似乎都会重新启动。为什么?
Initially, the enumerator is positioned before the first element in the collection. At this position, the
Current
property is undefined. Therefore, you must call theMoveNext
method to advance the enumerator to the first element of the collection before reading the value ofCurrent
.
要获得预期的行为并对值求和,您可以编写以下内容
var cumulative = 0d;
foreach (var enumerator in enumerators)
{
if (enumerator.MoveNext())
cumulative += enumerator.Current;
}
All
只是 return bool
值,它不会更改源序列或其项目。
Each time I access the enumerator via linq it seems to restart. Why?
Enumerator<T>
是 struct
和值类型,它不是 class。每次修改时,修改副本,源enumerators
列表中的元素保持不变,枚举器位于第一个元素
按照以下更改您的代码
var enumerators = signals.Select(l => l.GetEnumerator() as IEnumerator<double>).ToList();
按照这个 SO post
It is because the enumerator of List is a struct whereas the enumerator of Array is a class.
So when you call Enumerable.All with the struct, copy of enumerator is made and passed as a parameter to Func since structs are copied by value. So e.MoveNext is called on the copy, not the original.