Domanda

I seem to have an misunderstanding because the following code works correctly if I don't append the ToList() command:

IEnumerable<ProcessorInfo> query = (
        from n in InfoGet(EMachineInfoDepth.LogicalProcessor)
        select n
    )
    .ToList();

InfoGet looks like this:

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;
        }
    }
}

With ToList() I get the correct count, but all records equal the final element in the sequence. While I get that this could be a variable scope error in my complex coroutine, as in all iterations see the final value, why does the code work without ToList()?

My question is: what am I misunderstanding?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top