2013-02-05 4 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에게 초보자이며 내 Google 검색은 실제 과일을 가지고 있었기 때문에 나는 여기 묻을 것이라고 생각했다. :)

는 명확히하기 위해 : 나는 부품의 수를 계산하고

내가 그들 임의의 수의 코드가 호출 될 때마다 시간이 될 수있는이있을 수 있습니다. 따라서 BuildXmlBlob() 메서드가 호출 될 때마다 생성 된 XML에는 'partNumber'를 나타내는 고유 한 요소가 있습니다.

카운터가 현재 7 일 경우 이는 지금까지 7 번째 부분을 처리 중임을 의미합니다. 즉, BuildXmlBlob()에서 반환 된 XML에는 어딘가에 카운터 값이 포함됩니다. 그래서 내가 어떻게 든 전달되고 BuildXmlBlob()가 호출 될 때마다 증가시켜야합니다.

+0

왜 그 카운터가 필요한가요? 너 뭐야? 쿼리의 항목 수를 원하면'Count() '합니다. –

+0

그건 작동하지 않을 수도 있습니다. :). 코드를 호출 할 때마다 내가 가질 수있는 부품의 수를 세고 있습니다. – IbrarMumtaz

+0

'BuildXmlBlob() '에서 카운터 값이 사용되고 있습니까? 그렇다면,'out'을 사용하는 것은 매우 잘못된 것입니다. 어떤 것이라도'ref' 변수 여야합니다. –

답변

1

순수하게 LINQ로 유지하려는 경우 쿼리에서 사용하기 위해 실행 횟수를 유지해야하는 경우 가장 간단한 방법은 쿼리의 인덱스가 포함 된 오버로드를 사용하는 것입니다. 현재의 인덱스를 취득합니다.

이 경우 입력을 먼저 수집 한 다음 과부하를 사용하여 프로젝션을 수행하는 쿼리를 수행하는 것이 더 깔끔합니다.

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

은 내가 필요한 것을 위해 기초를 구축하고 단순히 오른쪽 끝에있는 select 문에 압정으로 고정하는 방법 사슬로 변환 ReSharper에서 사용했다.