C# 是否修改源项更改列表项?
我正在为一个使用C#中Windows窗体的软件编写一个小插件。 我需要解析一个XML文件来检索一些对象,并将它们添加到C# 是否修改源项更改列表项?,c#,winforms,listbox,C#,Winforms,Listbox,我正在为一个使用C#中Windows窗体的软件编写一个小插件。 我需要解析一个XML文件来检索一些对象,并将它们添加到列表框中。问题是,在我的程序结束时,所有对象都与最后添加的对象相同。 我知道了原因,但我仍在寻找解决方法。下面是一个使用字符串[]代替我的对象的小示例: static void Main(string[] args) { ListBox listbox = new ListBox(); String[] s = new string[] { "5", "2", "
列表框中。问题是,在我的程序结束时,所有对象都与最后添加的对象相同。
我知道了原因,但我仍在寻找解决方法。下面是一个使用字符串[]
代替我的对象的小示例:
static void Main(string[] args)
{
ListBox listbox = new ListBox();
String[] s = new string[] { "5", "2", "3" };
listbox.Items.Add(s);
s[2] = "0";
listbox.Items.Add(s);
Console.WriteLine(((String[])listbox.Items[0])[2]); // result => 0
Console.WriteLine(((String[])listbox.Items[1])[2]); // result => 0
Console.ReadLine();
}
它显示最后更新的值,因为字符串是引用类型,将在更新时替换所有现有引用。因此,您需要创建新数组,然后将其作为源添加到列表框中
static void Main(string[] args)
{
ListBox listbox = new ListBox();
String[] s = new string[] { "5", "2", "3" };
listbox.Items.Add(s);
String[] s2 = new string[] { "5", "2", "0" };
listbox.Items.Add(s2);
Console.WriteLine(((String[])listbox.Items[0])[2]); // result => 0
Console.WriteLine(((String[])listbox.Items[1])[2]); // result => 0
Console.ReadLine();
}
使用listbox.Items.Add代码>您只添加了一项,即数组本身。使用AddRange
来添加数组的元素
listbox.Items.AddRange(s);
另一种方法是设置:
让我们详细看看代码中发生了什么(行号)
创建并初始化一个数组李>
此数组作为一个项目添加到列表框中。请注意,数组是引用类型。因此,实际上,您只是添加了对列表框的引用,而不是数组的副本李>
数组的一个元素已更改。这也会影响添加到列表框的第一个项目,因为它包含对此唯一数组的引用李>
将相同的数组引用作为一项添加到列表框中。现在,ListBox包含两个项目,它们引用具有相同元素的相同数组
如果希望项目包含两个不同的数组,可以克隆该数组:
string[] s = new string[] { "5", "2", "3" };
listbox.Items.Add(s);
var s2 = (string[])s.Clone();
s2[2] = "0";
listbox.Items.Add(s2);
现在列表框中有两个不同的项。请注意,将创建一个浅克隆。也就是说,数组元素本身不是克隆的。因此,如果它们是引用类型,则两个数组在克隆后将包含相同的对象。但由于您有两个不同的数组,因此可以替换一个数组的元素而不影响另一个数组
您可以将克隆方法添加到自己的类中
public class MyOwnClass
{
public string Prop1 { get; set; }
public int Prop2 { get; set; }
public MyOwnClass ShallowClone()
{
return (MyOwnClass)MemberwiseClone();
}
}
MemberwiseClone
继承自系统。对象
列表框使用指针,更新第一个数组中的值,更新标记为“s”的指针的值,为了使用相同的值名但不同的数组,必须克隆起始数组
ListBox listbox = new ListBox();
String[] s = new string[] { "5", "2", "3" };
listbox.Items.Add(s);
s = (String[])s.Clone();
s[2] = "0";
listbox.Items.Add(s);
Console.WriteLine(((String[])listbox.Items[0])[2]); // result => 3
Console.WriteLine(((String[])listbox.Items[1])[2]); // result => 0
Console.ReadLine();
这是因为添加了相同的数组引用,所以在更新数组时,添加到列表框中的引用指向相同的已更改数组。如果你想避免这种情况,你需要创建一个新的数组。谢谢大家的建议!我要试一试。:)更新了我的答案
public class MyOwnClass
{
public string Prop1 { get; set; }
public int Prop2 { get; set; }
public MyOwnClass ShallowClone()
{
return (MyOwnClass)MemberwiseClone();
}
}
ListBox listbox = new ListBox();
String[] s = new string[] { "5", "2", "3" };
listbox.Items.Add(s);
s = (String[])s.Clone();
s[2] = "0";
listbox.Items.Add(s);
Console.WriteLine(((String[])listbox.Items[0])[2]); // result => 3
Console.WriteLine(((String[])listbox.Items[1])[2]); // result => 0
Console.ReadLine();