2010-12-02 6 views
0

어제 메서드를 작업하고 이상한 뭔가를 만났습니다. 여기 코드의 다운 된 버전이 있습니다. 기본적으로 문제는 OrderBy가 Bar.PopulateList 메서드가 지속되지 않습니다.메서드에 개체 전달 및 해당 개체에 대한 확장 메서드 호출


class Foo 
{ 
    List MyObjects; 

    public void PopulateMyObjects() 
    { 
     //Items are added to my list but the OrderBy is not persisting. 
     Bar.PopulateList(MyObjects); 
    } 
} 

class Bar 
{ 
    public static int PopulateList(List theList) 
    { 
     foreach(var in WebSerbiceCall) 
     { 
      theList.Add(var); 
     } 
     // the OrderBy call only sorts 'theList' in the context of this method. 
     // When I return from this method theList has been populated but the Ordering has 
     // reverted back to the order that the items were added to the list. 
     theList.OrderBy(obj => obj.ID); 
     return theList.Count; 
    } 
} 

지금은 코드를 업데이트하고 모든 작품은 아래에 따라 심판 키워드를 추가하는 경우 : 예를 들어, 공공 정적 int PopulateList (ref 목록 theList) 및 Bar.PopulateList (ref MyObjects);

누구든지 나를 계몽시킬 수 있습니까? 나는 물체가 항상 심판에 의해 지나간 줄 알았지? OrderBy가 확장 메소드인가요?

감사합니다, 기술자에게

답변

4

여기서 문제가 OrderBy 호출이 실제로하지 않는다는 것입니다

return theList.OrderBy(obj => obj.ID).Count; 

이 (내가 explaination를 추가하려고했지만 @jaredPar 그것을 설명하고있다) 어떤 식 으로든 theList을 돌연변이시켜야합니다. 대신 주문 된 새 IEnumerable<object>을 반환합니다. 따라서 메서드 외부에서 호출의 영향을 보지 못하는 이유는 단순히 개체를 변경하지 않기 때문입니다.

OrderBy 메서드를 사용하면 새 값이 만들어 지므로 호출하는 함수가이 새 값을 인식하게하려면 어떤 방식으로 반환해야합니다. 가장 일반적인 장소는 반환 값 또는 ref/out param입니다.

public static int PopulateList(ref List<object> theList) { 
    ... 
    theList = theList.OrderBy(obj => obj.ID).ToList(); 
} 
+0

나는 너무 그때, 나는 시도 : theList = thisList.OrderBy (obj => obj.ID) .ToList(); 아래 Matthew에 의해 언급되었지만 그것은 작동하지 않았다. 또한 ref 키워드를 추가하는 것이 왜 효과가 있습니까? – CianM

+0

@CianM'theList'가'out' 또는'ref' 매개 변수가 아니라면 여전히 작동하지 않을 것입니다. 그것 없이는 메서드 내에서 참조 복사본을 수정하는 것입니다. – JaredPar

+0

고마워요! 나는 이것을 이해할 수있는 다른 사람들을 위해 예쁜 그림으로 훌륭한 기사를 찾았습니다. http://rapidapplicationdevelopment.blogspot.com/2007/01/parameter-passing-in-c.html – CianM

1

시도 :

+0

정렬 된 열거 형은 정렬되지 않은 목록과 요소 수가 동일하지 않습니까? – dtb

+0

OrderBy 위에 코드가 있습니다. theList.Add (var); 그래서 나는 그것이 생각할 수 있다고 생각하지 않는다. – jwwishart

+0

그러나 OrderBy는 요소를 추가하거나 제거하지 않으므로 'theList.OrderBy (obj => obj.ID) .Count()'는'theList.Count'와 같아야합니다. – dtb

1

C#은 인수를 값으로 전달하지만 참조 유형의 값은 해당 메모리 위치의 포인터입니다. 당신은 결과를 할당하지 않을

theList.OrderBy(obj => obj.ID); 

:

theList = thisList.OrderBy(obj => obj.ID).ToList(); 
+0

안녕하세요, 이건 내가 orginally 너무 생각했지만 그것은 여전히 ​​작동하지 않았다. – CianM

0

ref 키워드를 사용하지 않으면 전달 된 매개 변수가 동일한 개체에 대한 새 참조입니다. 어떤 의미에서는 '참조로 전달'되지만 다소 다르게 생각해야합니다.

다른 대답은 정확합니다. OrderBy은 제자리에서 수행되지 않고 대신 순서가 지정된 컬렉션을 반환합니다. 그러나 매개 변수를 결과로 설정하면 기본 객체 자체를 변경하는 대신 매개 변수 (참조)의 값을 새 컬렉션을 가리 키도록 변경합니다. 예를 들어

,

theList = thisList.OrderBy(obj => obj.ID).ToList(); 

주문을, theList 소요 한 다음 새 목록을 작성합니다.그런 다음 목록에 대한 참조 인 theList의 값이 새로 생성 된 (정렬 된) 목록을 가리 키도록 변경됩니다. 이 메서드 외부에 만들어진 원래 참조는 여전히 원래의 정렬되지 않은 목록을 가리 킵니다.

.ToList()으로 전화 할 때마다 실제로 새 목록이 생성되기 때문입니다. ref 키워드를 사용하면 동일한 목록에 대한 새 참조를 만드는 대신 목록에 대한 참조가 들어있는 실제 변수를 전달합니다.

+0

고맙습니다. Thats는 정말 간결한 설명입니다. – CianM

+0

@CianM 건배는 나를 위해 나를 투표하게 자유롭게 느낀다! –