2013-02-05 41 views
0

我有以下的C#代碼:如何使用LinqToObjects維護計數器?

private XElement BuildXmlBlob(string id, Part part, out int counter) 
    { 
     // return some unique xml particular to the parameters passed 
     // remember to increment the counter also before returning. 
    } 

這是由叫做:

 var counter = 0; 
     result.AddRange(from rec in listOfRecordings 
         from par in rec.Parts 
         let id = GetId("mods", rec.CKey + par.UniqueId) 
         select BuildXmlBlob(id, par, counter)); 

上述示例代碼是象徵什麼,我想實現。

根據Eric Lippert的說法,out關鍵字和linq不會混合。確定不夠公平,但有人可以幫助我重構上述所以它工作?一位同事在工作中提到了累加器和聚合函數,但我是Linq的新手,我的谷歌搜索有任何真正的成果,所以我想我會問這裏:)。

澄清:

我指望零件的數量我可能有這可能是每次代碼被稱爲其中任意數量。所以每次調用BuildXmlBlob()方法時,生成的xml都會有一個唯一的元素表示'partNumber'。

所以如果計數器當前位於7,這意味着我們正在處理第7部分到目前爲止!這意味着從BuildXmlBlob()返回的XML將在其中嵌入計數器值。這就是爲什麼我需要它以某種方式被傳遞並在每次運行時調用BuildXmlBlob()時遞增。

+0

爲什麼你甚至需要那個櫃檯?你在計算什麼?如果你想要查詢中的項目數量,只需要「Count()」。 –

+0

這可能無法正常工作:)。我正在計算每次調用代碼時可能有的任意數量的部件數量。 – IbrarMumtaz

+0

計數器值是否在'BuildXmlBlob()'中使用?如果是這樣,使用'出'是非常誤導。如果有的話,它應該是一個'ref'變量。 –

回答

1

如果你想保持這種純粹的LINQ,並且你需要保持一個運行計數在你的查詢中使用,那麼最簡單的方法就是使用Select()重載,該重載包括查詢中的索引獲取當前的索引。

在這種情況下,執行查詢首先收集輸入,然後使用重載執行投影將會更清晰。

var inputs = 
    from recording in listOfRecordings 
    from part in recording.Parts 
    select new 
    { 
     Id = GetId("mods", recording.CKey + part.UniqueId), 
     Part = part, 
    }; 
result.AddRange(inputs.Select((x, i) => BuildXmlBlob(x.Id, x.Part, i))); 

那麼你就不需要使用out/ref參數。

XElement BuildXmlBlob(string id, Part part, int counter) 
{ 
    // implementation 
} 
+0

我設法得到類似的東西,所以謝謝。 – IbrarMumtaz

0

下面是我設法弄清楚我自己:。

  result.AddRange(listOfRecordings.SelectMany(rec => rec.Parts, (rec, par) => new {rec, par}) 
          .Select(@t => new 
           { 
            @t, 
            Id = GetStructMapItemId("mods", @t.rec.CKey + @t.par.UniqueId) 
           }) 
          .Select((@t, i) => BuildPartsDmdSec(@t.Id, @[email protected], i))); 

我用ReSharper的將其轉換成其構建的基礎知識,我需要什麼,然後,我只是上漲了就在年底的select語句的方法鏈。