複数のオブジェクトを追加する場合のリストの上書きについて
リストに複数のオブジェクトを追加すると、予期しない動作が発生する可能性があります。すべてのリスト エントリが、最後に追加されたオブジェクトと同じ値になる可能性があります。 これは、単一のオブジェクト インスタンスへの共有参照が原因で発生します。
例を見てみましょう:
<code class="language-csharp">public class Tag { public string TagName { get; set; } } List<Tag> tags = new List<Tag>(); Tag tag = new Tag(); // This is the problem! string[] tagList = new[] { "Foo", "Bar" }; foreach (string t in tagList) { tag.TagName = t; tags.Add(tag); }</code>
コードは、ループの外に 1 つの Tag
オブジェクト (tag
) を作成します。次に、ループはこの同じオブジェクトを繰り返し変更し、リストに追加します。 その結果、すべてのリスト エントリは同じオブジェクトを指し、最後の TagName
割り当てのみが反映されます。
解決策: ループ内に新しいインスタンスを作成する
これを修正するには、各反復のループTag
内に新しいオブジェクトを作成します。
<code class="language-csharp">foreach (string t in tagList) { Tag tag = new Tag(); // Create a new instance each time tag.TagName = t; tags.Add(tag); }</code>
これにより、各リスト エントリが独自の Tag
を持つ一意の TagName
オブジェクトを参照するようになります。
代替: 構造体の使用
C# のクラスは参照型です。 一方、構造体は値型です。 構造体を使用すると、リストに追加されるときに構造体のコピーが作成されるため、上書きの問題を回避できます。
<code class="language-csharp">public struct Tag { public string TagName { get; set; } } List<Tag> tags = new List<Tag>(); foreach (string t in tagList) { Tag tag = new Tag { TagName = t }; //Creates a new instance each time tags.Add(tag); }</code>
このアプローチは、構造体の固有のコピーオン代入動作を活用することで、簡潔で効率的なソリューションを提供します。 ただし、構造体は、それが表すデータに適した場合にのみ慎重に使用する必要があることに注意してください。
以上が複数のオブジェクトをリストに追加すると、以前のエントリが上書きされるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。