0

我似乎有一个误解,因为如果我不附加 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() 的情况下工作?

我的问题是:我误解了什么?

4

1 回答 1

1

Problem is, you're returning reference to the same variable all the time:

ProcessorInfo result = new ProcessorInfo();

That's the only place you're actually creating new ProcessorInfo object. You only change it's properties values later, but return still the same object.

You should consider adding copy constructor into your ProcessorInfo() class, and replace every yield return result; call with yield return new ProcessorInfo(result);. That would be the easiest way to make it work.

Update

It could look like it works e.g. when you've saved some variable state somewhere during loop:

foreach(var item in query)
{
    itemsList.Add(item);
    propertyList.Add(item.IntProperty);
}

After that call itemsList will contain incorrect data, while propertyList will be just fine.

于 2013-04-20T07:16:09.433 回答