2013-04-20 62 views
0

我似乎有一個誤解,因爲下面的代碼工作正常,如果我不追加ToList()命令:LINQ 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; 
     } 
    } 
} 

With ToList()我得到正確的計數,但所有記錄等於序列中的最後一個元素。雖然我知道這可能是我的複雜協程中的變量範圍錯誤,因爲在所有迭代中都會看到最終值,爲什麼代碼在沒有ToList()的情況下工作?

我的問題是:我誤解了什麼?

回答

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會就好了。

+0

我想這是,但爲什麼它沒有ToList()? – IamIC 2013-04-20 07:19:42

+0

*它是什麼意思*它的作品*?你如何檢查它?它將工作*用於像First(OrDefault),ElementAt(OrDefault),Count和類似的方法,因爲它們在當時只檢查/返回一個元素。 – MarcinJuraszek 2013-04-20 07:20:06

+0

我通過集合枚舉並將輸出轉儲爲CSV。 foreach(InfoGet中的var item {深度})...寫入CSV的數據是正確的 – IamIC 2013-04-20 07:23:06