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

問題は、常に同じ変数への参照を返していることです。

ProcessorInfo result = new ProcessorInfo();

それは、実際に新しいProcessorInfoオブジェクトを作成している唯一の場所です。後でプロパティ値を変更するだけで、同じオブジェクトが返されます。

クラスにコピー コンストラクターを追加することを検討しProcessorInfo()、すべてのyield return result;呼び出しをyield return new ProcessorInfo(result);. それが機能させる最も簡単な方法です。

アップデート

たとえば、ループ中に変数の状態をどこかに保存した場合など、機能するように見える場合があります。

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

その後、呼び出しには正しくないitemsListデータが含まれますが、 whileは問題ありません。propertyList

于 2013-04-20T07:16:09.433 に答える