2015-01-08 3 views
0

그래서컬렉션을 함수에 전달하면 함수가 컬렉션의 요소를 변경할 수 있다는 의미입니까?

... 실제로 질문 (내가 생각하는)에 대한 답을 알고 있지만 내가 이유를 모르는, 내가 알고 나는 다음과 같은 클래스가있는 경우 :

class Man 
{ 
    public string Name; 
    public int Height; 

    public Man() { } 
    public Man(string i_name, int i_height) 
    { 
     Name = i_name; 
     Height = i_height; 
    } 

}  

을 그리고 (주 기능) 다음과 같은 프로그램 클래스가 :

class Program 
{ 
    static void Main(string[] args) 
    { 
     Program p = new Program(); 
     Man g = new Man("greg", 175); 

     //assigning null to g inside the function. 
     p.ChangeMan(g); 


     Console.WriteLine(g == null? "the function changed g out side the function" : "the function did not change g out side the function"); 
     //the output of course is that the function did not change g outside the function. 

     //now I am creating a list of Man and adding 5 Man instances to it. 

     List<Man> manList = new List<Man>(); 
     for (int i = 0; i < 5; i++) 
     { 
      manList.Add(new Man("Gadi" + i.ToString(), 10 * i)); 
     } 

     //assigning null to the list insdie the function 
     p.ChangeList(manList); 
     Console.WriteLine(manList == null ? "the function changed the list out side the function" : "the function did not change the list out side the function"); 
     //the output of cousre again is the function did not change the list out side the function 

     //now comes the part I dont understand... 


     p.ChangeManInAList(manList); 

     Console.WriteLine("list count = " + manList.Count()); 
     //count is now 6. 

     Console.WriteLine(manList[0] == null ? "the function changed the element out side the function" : "the function did not change the element out side the function"); 
     //the out again - the function did not change... 


    } 

    public void ChangeMan(Man g) 
    { 
     g = null; 
    } 

    public void ChangeManInAList(IList<Man> gadiList) 
    { 
     Man g = gadiList.First<Man>(); 
     g = null; 
     Console.WriteLine(g == null? "g is null" : "g is not null"); 

     gadiList.Add(new Man("a new gadi", 200)); 
     Console.WriteLine("list count = " + gadiList.Count()); 
    } 

    public void ChangeList(List<Man> list) 
    { 
     list = null; 
    } 


} 

나는 목록에 한 사람을 추가하는 목록 +의 첫 번째 요소에 null을 할당하고있다. 목록에 추가 할 수 있으면 요소를 변경할 수도 있지만 다른 것을 보았습니다 ...

목록에 Man을 추가 할 수 있었지만 요소 중 하나에 null을 할당 할 수 없었습니다. 어째서? 목록 자체가 변경 될 수 없으므로 목록에 값이 전달된다는 것을 알고 있습니다 (null을 할당하는 것과 같이). 그러나 추가 할 수 있습니까? 요소에 null을 할당 할 수 없습니까? 그들은 val에 의해 또한 통과되고 있는가?

좋은 및 명확한 설명 : 여기에

+3

는 참조 http://pobox.com/~skeet/csharp/parameters.html –

+0

"Console.WriteLine (g == null이?"함수 목록 Console.WriteLine " 이 안"에 의해 변경 (manList == null? "함수는 목록을 변경했다"? – Landeeyo

+0

네, 맞았지 만 출력은 같습니다 :) – JimmyBoy

답변

3

에 대한 드릴 것입니다 혼란의 요점입니다 :

Man g = gadiList.First<Man>(); 
g = null; 

당신이 기본적으로 목록 밖으로 Man을 받고에 할당되는 일을 지역 변수 g.
그런 다음 g 변수에 다른 값을 할당합니다.

여기서 목록의 구성원 값을 변경하지 않았 으면 변수 g이 참조하는 값을 변경하기 만하면됩니다.

의이 예와 비교 해보자 :

int a = 5; 
int b = a; 
b = 3; 
//you wouldn't expect `a` to be 3 now, would you? 

을 명시 적으로 다른 값으로 목록 인덱스를 설정해야 목록 항목의 값을 변경하려면 :

Man g = gadiList.First<Man>(); 
gadiList[gadiList.IndexOf(g)] = null; 

//or specifically in this case: 
gadiList[0] = null; 
+0

은 또 다른 질문으로 이어집니다 : 그래서, 나는 그 요소를 무효화 할 수있는 것을 보았습니다. 그것을 보호 할 수있는 방법이 있습니까? 나는 기능을 제공하는 사용자가 우연히 내 요소를 널 싶지 않다 ... – JimmyBoy

+1

@JimmyBoy'ReadOnlyCollection'을 들여다. – Rotem

+0

@JimmyBoy 무엇을 의미 하는가? 당신은 오직'gadiList [i] = null;'을 수행함으로써 "null 요소 만"할 수 있습니다. –

0

목록에서 요소를 가져올 때 목록 항목에 대한 새로운 참조를 얻습니다. 결과적으로 두 개의 참조 (목록 개체의 비공개 참조), 참조를 얻을 수 있습니다. 참조를 null로 설정하면 목록 개체의 참조에는 영향을주지 않습니다. 참조가 null이되었지만 비공개 목록 참조가 동일하게 유지됩니다.