C# 목록 개체 값을 덮어썼습니다. 참조 의미 문제
목록에 새 값을 추가하면 목록의 모든 항목이 이전 값을 덮어쓰는 이유는 무엇인가요? 이 수수께끼 같은 동작은 C#의 기본 데이터 구조와 참조 의미 체계에서 비롯됩니다.
클래스와 구조의 의미 이해
C#에서 클래스는 참조 유형입니다. 즉, 클래스 유형의 변수는 메모리의 실제 개체 위치에 대한 참조를 저장합니다. 반면에 구조는 값 유형이며 변수는 실제 데이터를 직접 보유합니다.
제공된 코드 조각에서:
<code class="language-csharp">List<Tag> tags = new List<Tag>(); Tag _tag = new Tag(); string[] tagList = new[] { "Foo", "Bar" }; foreach (string t in tagList) { _tag.tagName = t; // 设置所有属性 tags.Add(_tag); // 覆盖之前的数值 }</code>
_tag
은 참조 유형이므로 tags.Add(_tag)
작업은 동일한 개체에 대한 참조를 목록에 추가합니다. 결과적으로 목록의 모든 요소는 실제로 동일한 인스턴스를 가리킵니다. _tag
을 통해 인스턴스를 수정하면 목록의 모든 항목이 변경됩니다.
새 인스턴스를 생성하여 문제 해결
덮어쓰기를 방지하려면 루프가 반복될 때마다 새 Tag
인스턴스를 생성해야 합니다.
<code class="language-csharp">foreach (string t in tagList) { Tag _tag = new Tag(); // 为每次迭代创建一个新实例 _tag.tagName = t; tags.Add(_tag); }</code>
이제 각 반복은 새로운 Tag
인스턴스를 생성하여 목록의 각 개체가 고유한 값을 갖도록 합니다.
추가 참고 사항: 구조 및 클래스
클래스 대신 구조체를 사용하면 구조체가 값 유형이므로 덮어쓰기 문제가 사라집니다. 구조가 새 변수에 할당되면 자체 값 세트를 포함하는 완전히 새로운 인스턴스가 생성됩니다. 따라서 tags.Add(_tag)
은 복사 작업을 수행하며 이전에 추가된 항목에는 영향을 주지 않습니다.
요약하자면, C#의 개체 목록 덮어쓰기 문제를 방지하려면 참조 의미 체계와 클래스와 구조체 간의 차이점을 이해하는 것이 중요합니다.
위 내용은 C#에서 내 목록 항목이 서로 덮어쓰는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!