您好我有一个Person类列表如下
public class person
{
public int age;
public string name;
}
我正在尝试执行以下操作。
static void Main(string[] args)
{
List<person> person1 = new List<person>();
person1.Add(new person { age = 10, name = "P1" });
person1.Add(new person { age = 11, name = "Q1" });
person1.Add(new person { age = 12, name = "R1" });
List<person> person2 = new List<person>(person1);
person2[0].name = "P2";
Console.WriteLine("---------Person1---------");
foreach (person P in person1)
{
Console.WriteLine("Age=" + P.age);
Console.WriteLine("Name=" + P.name);
}
Console.WriteLine("---------Person2---------");
foreach (person P in person2)
{
Console.WriteLine("Age=" + P.age);
Console.WriteLine("Name=" + P.name);
}
}
输出是两个列表中第一个对象的值更改为P2,而我希望仅在person2
列表中更改它。我以为列表项会被复制到person2
列表中。
MSDN here表示将元素复制到新列表中,这在上述情况下不会发生。我在这里错过了什么?
答案 0 :(得分:1)
你在这里犯的错误是参考变量。列表中包含对person
类型对象的引用。复制列表时,它只复制对这些对象的引用,因此每个列表都包含对完全相同对象集的引用。
有关我正在讨论的更深入的示例,请考虑以下代码:
person me = new person { age = 20, name = "Lauraducky" };
person you = me;
you.name = "Programmerzzz";
Console.WriteLine(me.name); // Outputs Programmerzzz
这基本上就是你在你的例子中所做的。 me
变量不会被复制,对它的引用只会被传递给you
变量。然后更改该参考位置处的对象。这里的关键是两个变量都指向同一个位置。
如果要制作列表的深层副本,则必须手动执行此操作。例如:
List<person> person2 = new List<person>();
foreach (person p in person1) {
person2.Add(new person { age = p.age, name = p.name });
}
有关参考类型的更多信息,请参阅this excellent explanation。
答案 1 :(得分:0)
类是按引用复制的,struct是按值复制的。
因此,您更改了人员的价值,您将链接到原始参考。
public Struct person
{
public int age;
public string name;
}
如果您使用struct,请再试一次,您会看到不同的
答案 2 :(得分:0)
您通过引用而不是按值复制。首先要做的是修好你的课程。所以你可以创造“人”。使用构造函数的对象。下面的代码创建了一个新对象,而不是复制前一个列表的引用。
public static void Main()
{
Console.WriteLine("Program Started!");
List<person> person1 = new List<person>();
person1.Add(new person(10, "P1" ));
person1.Add(new person( 11, "Q1" ));
person1.Add(new person(12, "R1" ));
List<person> person2 = new List<person>();
foreach(person p in person1)
{
person2.Add(new person(p)); //WE COPY BY VALUE. BY ALLOCATING SPACE FOR A NEW OBJECT.
}
person2[0].name = "P2";
Console.WriteLine("---------Person1---------");
foreach (person P in person1)
{
Console.WriteLine("Age=" + P.age);
Console.WriteLine("Name=" + P.name);
}
Console.WriteLine("---------Person2---------");
foreach (person P in person2)
{
Console.WriteLine("Age=" + P.age);
Console.WriteLine("Name=" + P.name);
}
Console.WriteLine("Program Ended!");
Console.ReadKey();
}
public class person
{
public int age;
public string name;
public person(person p) {
this.age = p.age;
this.name = p.name;
}
public person(int _age, string _name)
{
this.age = _age;
this.name = _name;
}
}