我试图理解下面的代码出了什么问题。
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访问枚举器时,它似乎都重新启动。为什么?
根据下面更改代码
var enumerators = signals.Select(l => l.GetEnumerator() as IEnumerator<double>).ToList();
根据此SO post
这是因为List的枚举数是一个结构,而Array的枚举数是一个类。
因此,当您使用struct调用Enumerable.All时,将创建枚举数的副本并将其作为参数传递给Func,因为结构是按值复制的。因此,将在副本上调用e.MoveNext,而不是原始副本。
根据docs
最初,枚举器位于中的第一个元素之前集合。在此位置,
Current
属性未定义。因此,必须调用MoveNext
方法来推进枚举器到集合的第一个元素,然后再读取Current
。
此外,要获得预期的行为和总和,您可以编写以下内容
var cumulative = 0d;
foreach (var enumerator in enumerators)
{
if (enumerator.MoveNext())
cumulative += enumerator.Current;
}
All
仅返回bool
值,它不会更改源序列,因此也不会返回它。
每次我通过linq访问枚举器时,它似乎都重新启动。为什么?
Enumerator<T>
是struct
和值类型,它不是类。每次修改时,都修改副本