我一直在努力寻找一些我发现非常奇怪的东西。显然,C#表现得这样,但我想知道如何防止它。我的代码很长,所以我做了一个我的困境的小例子:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
private List<Person> m_Persons = new List<Person>();
public Form1()
{
InitializeComponent();
Person p1 = new Person();
p1.Name = "Jack";
p1.Money = 10;
m_Persons.Add(p1);
Bank ph = new Bank();
for (int i = 0; i < 4; i++)
{
ph.Insert(p1);
Console.WriteLine(p1.Money);
}
}
}
class Person
{
public string Name { get; set; }
public int Money { get; set; }
}
class Bank
{
private List<Person> m_Customers = new List<Person>();
public void Insert(Person p_Person)
{
int index = m_Customers.FindIndex(item => item.Name == p_Person.Name);
if (index > -1)
m_Customers.ElementAt(index).Money += p_Person.Money;
else
m_Customers.Add(p_Person);
}
}
}
在上面的代码中,我的印刷品说:
10
20
40
80
这些值对我来说是对的,但是它们应该存储在bankclass中,而不是存储在Insert()
中用作引用的对象中。为什么p1-object会更新?!
答案 0 :(得分:6)
Person
是一个类,即引用类型。当您将人员插入m_Customers
列表时,实际上是在为同一个人实例创建新的引用,并将此引用添加到列表中(list hold 引用到人物实例)。因此,您的程序有一个person实例和六个对此实例的引用。使用哪个参考资料来更新人的钱并不重要 - 您的单个实例将在最后更新。
我还建议您阅读MSDN文章Value and Reference Types
答案 1 :(得分:3)
p1对象正在更新,因为Person
是引用类型。这意味着当您将对象传递给方法时,它实际上是对正在传递的对象的引用,即p1对象与您添加到的Person
完全相同。银行。因此,如果您更新银行中的Person
(在调用Insert
方法时执行此操作),则p1对象也会更新。
如果要防止此行为,则必须在循环中创建新的Person
对象。如果您每次将新的Person
对象的属性设置为相同的值,则会更新银行中的Person
,但不会更新循环中的Person
对象。< / p>
或者,您可以更改Insert方法,而不是
m_Customers.Add(p_Person);
你使用
m_Customers.Add(new Person{ Name = p_Person.Name, Money = p_Person.Money });
答案 2 :(得分:1)
似乎你总是在哄同一个人:
for (int i = 0; i < 4; i++)
{
ph.Insert(p1);
Console.WriteLine(p1.Money);
}
以上代码将插入p1
4次。
答案 3 :(得分:1)
在您的Insert
方法中,验证此人是否已存在于列表m_Customers中(如果存在),您可以更新资金。
在Form1
班级中,您需要创建不同姓名的人,如果名称相同,则会更新资金。
尝试在for
语句中创建人员,并使用不同的名称:
public Form1()
{
InitializeComponent();
Bank ph = new Bank();
for (int i = 0; i < 4; i++)
{
Person p = new Person();
p.Name = "Jack" + i;
p.Money = 10;
m_Persons.Add(p);
ph.Insert(p);
Console.WriteLine(p.Money);
}
}