gpt4 book ai didi

c# - 如何将 List 对象项目正确存储到 List 的另一个实例而不影响其单个项目值 - C#

转载 作者:太空宇宙 更新时间:2023-11-03 18:24:55 24 4
gpt4 key购买 nike

问题是:

我有这个类 Person :

class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Position { get; set; }
public int Age { get; set; }
}

我将这个名为 workersA 的对象初始化为源对象:

List<Person> workersA = new List<Person>()
{
new Person { Id = 1, Name = "Emp1", Age = 27 },
new Person { Id = 2, Name = "Emp2", Age = 18 },
new Person { Id = 3, Name = "Emp3", Age = 23 },
};

我将另外两个实例声明为:

List<Person> workersB = new List<Person>();
List<Person> workersC = new List<Person>();

并用不同的方法填充它:

workersB 上使用 .ToList() 扩展从源存储。

workersB = workersA.ToList();

并且在 workersC 上使用 foreach 语句从源存储。

foreach (var w in workersA.ToList())
{
workersC.Add(w);
}

现在,当我尝试修改源对象的 Age 属性时,代码如下:

foreach (var p in workersA.ToList())
{
p.Age--;
}

并使用这段代码输出所有结果:

Console.WriteLine("Wokers A:");
foreach (var p in workersA.ToList())
{
Console.WriteLine("Id: {0} Name: {1}, Age: {2}", p.Id, p.Name, p.Age);
}

Console.WriteLine();
Console.WriteLine("Wokers B:");
foreach (var p in workersB.ToList())
{
Console.WriteLine("Id: {0} Name: {1}, Age: {2}", p.Id, p.Name, p.Age);
}

Console.WriteLine();
Console.WriteLine("Wokers B:");
foreach (var p in workersB.ToList())
{
Console.WriteLine("Id: {0} Name: {1}, Age: {2}", p.Id, p.Name, p.Age);
}

这是我得到的:

Wokers A:
Id: 1 Name: Emp1, Age: 26
Id: 2 Name: Emp2, Age: 17
Id: 3 Name: Emp3, Age: 22

Wokers B:
Id: 1 Name: Emp1, Age: 26 // 27 - expectation
Id: 2 Name: Emp2, Age: 17 // 18 - expectation
Id: 3 Name: Emp3, Age: 22 // 22 - expectation

Wokers C:
Id: 1 Name: Emp1, Age: 26 // 27 - expectation
Id: 2 Name: Emp2, Age: 17 // 18 - expectation
Id: 3 Name: Emp3, Age: 22 // 22 - expectation

把问题说清楚

Why did i get the same output?

最佳答案

因为最终,workersBworkersC 中的每个元素仍将指向您最初创建的单个 Person 实例。因此它们都引用相同的实例 - 因此您得到相同的结果。

简而言之,您得到了三个不同列表,其中包含三个相同 Person 实例

当你这样做时:

workersB = workersA.ToList();

您创建了 List 的新实例,不是 List 中单个对象的新实例。同样,当您这样做时:

foreach (var w in workersA.ToList())
{
workersC.Add(w);
}

您正在将 workersA 中的相同 Person 引用传递给 workersC但是它们都指的是相同的 Person 实例。

所以当你最终这样做时:

foreach (var p in workersA.ToList())
{
p.Age--;
}

每个 Person 实例的 Age 都已更改,尽管包含它们的三个不同列表。


解决方案:

如果你真的想将不同的 Person 传递给三个列表,一种方法是为 Person 实现一个 Clone 方法(您会在 IClonable 界面中找到):

public Person Clone(){
return new Person() { Id = this.Id, Name = this.Name, Age = this.Age };
}

然后您使用 Clone 而不是原始的 Person 输入其他列表:

foreach (var w in workersA.ToList())
{
workersC.Add(w.Clone()); //use Clone here
}

编辑 2,根据 chat OP 的最终解决方案

class Person : ICloneable 
{
public int Id { get; set; }
public string Name { get; set; }
public string Position { get; set; }
public int Age { get; set; }

public Person Clone()
{
return (Person)this.MemberwiseClone();
}

object ICloneable.Clone()
{
return this.Clone();
}

}

关于c# - 如何将 List<T> 对象项目正确存储到 List<T> 的另一个实例而不影响其单个项目值 - C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36737861/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com