Microsoft MVP성태의 닷넷 이야기
C# list.Clear() 호출에 대한 문의 드립니다. [링크 복사], [링크+제목 복사]
조회: 5134
글쓴 사람
김현진 (kutgw at naver.com)
홈페이지
첨부 파일
 

안녕하세요.
사이트는 자주 방문하여 좋은 정보를 많이 얻었으나, 이렇게 문의 글을 올리는 것은 처음이네요.


응용프로그램 개발을 하는 중에 추가하고 싶은 기능이 생겨 함수를 작성하였는데,
생각처럼 동작이 되질 않았습니다. 디버깅을 통해 해결을 하였으나, 왜 그런지에 대한 이유를 알고싶어 문의를 드리게 되었습니다.
(개발환경은 Visual Studio 2019 , .NET Framework 4.7.2 입니다.)

아래의 내용은 xml 파일 내용을 읽어들이며 Dictionary 에 저장하는 함수인데,
foreach 문의 Loop 를 도는 중에 pcblist.Clear() 가 호출될 경우에는 Dictionary에 저장한 list 자료가 남아있지만,
foreach 문 Loop 마지막에서 pcblist.Clear() 호출될 경우에는 이미 저장한 Dictionary의 list 자료까지 모두 Clear가 됩니다.


public bool LoadDictionary()
{
    string path = Path.Combine(DataRootPath, "MagazineDictionary.xml");
    XDocument xdoc = XDocument.Load(path);
    
    List<PCB> pcbList = new List<PCB>(16);

    int pcbCount = 0;
    int magzineCount = xdoc.Descendants("Magazine").Count();
    if (magzineCount == 0)
    {
        return false;
    }

    foreach (XElement elem in xdoc.Descendants().Where(a => !a.HasElements))
    {
        var pcb = new PCB()
        {
            ID = elem.Attribute("ID").Value,
            No = elem.Attribute("No").Value,
            Status = Convert.ToInt32(elem.Attribute("Status").Value)
        };
        pcbList.Add(pcb);
        pcbCount++;

        if (pcbCount != 16)
        {
            continue;
        }

        if (!MD.ContainsKey(elem.Parent.Attribute("ID").Value))
        {
            MD.Add(elem.Parent.Attribute("ID").Value, new MGZ()
            {
                ID = elem.Parent.Attribute("ID").Value,
                No = elem.Parent.Attribute("No").Value,
                PCB_List = pcbList
            });
        }
        
        pcbCount = 0;
        pcbList.Clear();
    }
    return true;
}

MD 라는 Dictionary 에 저장한 Data 가 3개라면, 2개까지는 모두 정상적으로 Dictionary 에 저장됩니다.
마지막 3번째 Data 를 저장하고, list.Clear() 가 호출된 후 foreach 문을 빠져나오면 Dictionary 에 저장되어있는
PCB_List 가 모두 삭제가 됩니다.


프로그램을 시작한지 얼마되지 않아 많이 부족하네요.
이유에 대한 설명 좀 부탁드리겠습니다.

감사합니다.








[최초 등록일: ]
[최종 수정일: 11/21/2021]


비밀번호

댓글 작성자
 



2021-11-21 05시36분
"PCB_List = pcbList"는 리스트의 목록이 복사되어 대입되는 것이 아닙니다. 단순히 PCB_List의 속성은 pcblist에 대한 참조값만을 담고 있는 것이기 때문에, pcblist.Clear를 해버리면 PCB_List.Clear를 호출한 것과 동일합니다. (그나저나, 원하는 것이 무엇인지 저 코드만 봐서는 잘 눈에 들어오지 않는군요. ^^;)
정성태
2021-11-21 06시36분
[김현진] 안녕하세요. 답변 감사드립니다.
디버깅하는 걸 캡쳐하여 첨부하고자 하였는데 문의글 수정이 안되네요.
말씀하신 것처럼 참조값만 담고 있어 pcblist.Clear를 해버리면 위 코드 상 PCB_List 에는 값이 항상 없어야 정상인 것으로 이해됩니다.
하지만, foreach 문의 loop 마지막에서 pcblist.Clear 가 호출될 때에만 PCB_List의 값이 모두 clear 가 되어 의문이 들었습니다.
해결한 방법도 loop 마지막에서 pcblist.Clear 가 호출되지 않도록 하였습니다.

귀한 시간 할애 해주셨는데, 설명이 부족하여 정확한 답볍을 들을 수가 없었네요. 죄송합니다.
좀 더 자세한 설명과 첨부 자료를 준비하여 다시 문의를 드리도록 하겠습니다.
[guest]
2021-11-22 09시43분
프로그램의 의도를 파악할 수 없어 잘은 모르겠지만. 그리고 foreach 문의 loop 마지막이라는 것은 루프 밖을 의미하는 것인지, 루프를 벗어나기 바로 전을 의미하는 것인지 질문의 의도가 불명확한 것도 있고요.

그냥 loop 마지막이라는 것을 loop를 벗어나서 pcblist.Clear를 호출한 걸로 가정해 보겠습니다.

그런 경우, 중간에 pcbCount != 16 / continue 조건에 의해 16번째에 해당하는 pcbCount가 오지 않는 한 루프 벗어나기 전의 pcblist.Clear가 호출되지 않으므로 MD에 있는 값이 남아 있는 것 아닌가요?

혹시 다음에 질문하시거든, 재현 가능한 예제를 첨부해주세요.
정성태
2021-11-22 05시22분
[김현진] 편법으로 pcblist.Clear() 호출을 막았던 것이 정확한 방법이 아니라는 생각에 코드를 다시 작성하여 해결하였습니다.

질문 내용이 명확하지 않다면, 답변을 들을 수 없다는 것을 다시 한 번 배웁니다.
다음에 질문 시에는 좀 더 명확한 내용과 예제로 질문하도록 하겠습니다.
감사합니다.
[guest]

... 16  17  18  [19]  20  21  22  23  24  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
5455한예지 donator1/16/20216388교재 194페이지 콜백메서드 질문 있습니다! [5]
5454한예지 donator1/15/20216033교재 208쪽 질문....있습니다... [3]
5453안녕하세요1/15/20217475C# dll 파일을 C++에서 사용 시 memory leak 문제 [2]파일 다운로드1
5452예지1/15/20216607var를 사용할 수 없는 이유가 궁금합니다! [3]
5451예지1/14/20215460for문의 초기식에 대해 질문드립니다. [3]
5450예지1/13/20215468Action 델리게이트 사용법 질문있습니다! [2]
5449김성민1/13/20216168Winform UserControl 상속 vs 감싸기? [2]
5448서형주1/13/20215901안녕하세요~~ DataGridView에 데이터를 표시하는 동작방법이 궁금합니다. [2]
5447종범1/11/20217553[WPF/OpenCV] 이미지->영상 저장에 대해서 질문 드립니다!! [5]파일 다운로드1
5446민우1/11/20215552닷넷 런타임을 dll 파일로 포함시킬수 있나요? [2]
5445정도현1/8/20215327directShow RenderFile 관련 재질문드립니다 [5]파일 다운로드1
5444정도현1/8/20215305directShow RenderFile 관련 질문드립니다 [3]
5443윤영호1/7/20215687xml 파일에서 데이터를 가지고 와서 list에 넣는 것을 질문드리고 싶습니다. [1]파일 다운로드1
5442진우1/4/20215476DB연결 객체나 파일 등은 GC 에서 관리해주지 않는 이유가 궁금합니다. [2]
5441한예지 donator1/4/20215914DB 연결 방법 질문 있습니다. [1]
5440한예지 donator1/1/20216515추상클래스로와 new [4]
5439이상호12/31/20208058VC 프로젝트 에서 _main 함수에서 참조되는 확인할 수 없는 외부 기호 [4]파일 다운로드1
5438김윤12/29/202010199C# winform using으로인한 메모리 해제 타이밍과 변수 복사 타이밍 [2]
5437한예지 donator12/25/20207266for문 안에 있는 지역변수의 생성 및 유지 기간에 대해 질문드립니다! [6]
5436영귤12/24/20205978fixed는 자동으로 stackalloc이 되는 건가요? [1]
5435한예지 donator12/24/20205794ArraySegment, Span, ReadOnlySpan 질문있습니다! [1]
5434한예지 donator12/23/20206362ToString 재정의 질문있습니다! [8]
5433한예지 donator12/23/20206344List<ArrarySegment<int>> 사용법 질문드립니다! [2]
5431한예지 donator12/17/20208189비동기 소켓 서버 질문 드립니다! [1]
5430종범12/16/20207326[WPF] Task 관련 재질문 드립니다. [2]파일 다운로드1
5429종범12/16/20207243[WPF] Task 관련 질문 드립니다. [1]파일 다운로드1
... 16  17  18  [19]  20  21  22  23  24  25  26  27  28  29  30  ...