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中文網其他相關文章!