我似乎有一个误解,因为如果我不附加ToList()命令,以下代码可以正常工作:
IEnumerable<ProcessorInfo> query = (
from n in InfoGet(EMachineInfoDepth.LogicalProcessor)
select n
)
.ToList();
InfoGet看起来像这样:
internal static IEnumerable<ProcessorInfo> InfoGet(EMachineInfoDepth depth)
{
ProcessorInfo result = new ProcessorInfo();
// loop through all workgroups
foreach (Workgroup wg in workgroups_S)
{
result.Workgroup = wg;
if (depth >= EMachineInfoDepth.NUMANode)
{
// loop through all NUMANodes
foreach (NUMANode node in wg.NUMANodes)
{
result.NUMANode = node;
if (depth >= EMachineInfoDepth.CPU)
{
// loop through all CPUs
foreach (CPU cpu in node.CPUs)
{
result.CPU = cpu;
if (depth >= EMachineInfoDepth.Core)
{
// loop through all Cores
foreach (Core core in cpu.Cores)
{
result.Core = core;
if (depth >= EMachineInfoDepth.LogicalProcessor)
{
// loop through all LogicalProcessors
foreach (LogicalProcessor lp in core.LogicalProcessors)
{
result.LogicalProc = lp;
yield return result;
}
}
else
{
yield return result;
}
}
}
else
{
yield return result;
}
}
}
else
{
yield return result;
}
}
}
else
{
yield return result;
}
}
}
使用ToList(),我得到正确的计数,但所有记录都等于序列中的最后一个元素。虽然我知道这可能是我的复杂协程中的变量范围错误,因为在所有迭代中都会看到最终值,为什么代码在没有ToList()的情况下工作?
我的问题是:我误解了什么?
答案 0 :(得分:1)
问题是,你一直在返回对同一个变量的引用:
ProcessorInfo result = new ProcessorInfo();
这是您实际创建新ProcessorInfo
对象的唯一地方。您稍后只更改它的属性值,但仍然返回相同的对象。
您应该考虑在ProcessorInfo()
课程中添加copy constructor,并用yield return result;
替换每个yield return new ProcessorInfo(result);
来电。这将是使其发挥作用的最简单方法。
的更新强> 的
它可以看起来就像它有效一样当你在循环期间在某处保存了一些变量状态时:
foreach(var item in query)
{
itemsList.Add(item);
propertyList.Add(item.IntProperty);
}
此致电话itemsList
将包含不正确的数据,而propertyList
就可以了。