首页 >后端开发 >C++ >为什么我的列表项在 C# 中相互覆盖?

为什么我的列表项在 C# 中相互覆盖?

Barbara Streisand
Barbara Streisand原创
2025-01-19 20:11:09853浏览

Why are My List Items Overwriting Each Other in C#?

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn