我正在使用C#中的Windows窗体为软件编写一个小插件。
我需要解析XML文件以检索一些对象并将它们添加到ListBox
中。问题在于,在我的程序结束时,所有对象都与最后添加的对象相同。
我有点想出原因,但我仍在寻找解决方法。这是一个用String[]
代替我的对象的小例子:
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();
}
答案 0 :(得分:0)
使用listbox.Items.Add(s);
,您只添加了一项本身就是数组。使用AddRange
代替添加数组的元素。
listbox.Items.AddRange(s);
使其生效的另一种方法是设置DataSource
:
listbox.DataSource = s;
让我们详细了解您的编码中发生了什么(带有行号)
1 String[] s = new string[] { "5", "2", "3" };
2 listbox.Items.Add(s);
3 s[2] = "0";
4 listbox.Items.Add(s);
如果希望项目包含2个不同的数组,则可以克隆该数组:
string[] s = new string[] { "5", "2", "3" };
listbox.Items.Add(s);
var s2 = (string[])s.Clone();
s2[2] = "0";
listbox.Items.Add(s2);
现在,列表框中有两个不同的项目。请注意,Array.Clone Method创建了一个浅表克隆。即数组元素本身不会被克隆。因此,如果它们是引用类型,则两个数组在克隆后将包含相同的对象。但是由于您有2个不同的数组,因此可以替换一个数组的元素而不会影响另一个数组。
您可以将克隆方法添加到自己的类中
public class MyOwnClass
{
public string Prop1 { get; set; }
public int Prop2 { get; set; }
public MyOwnClass ShallowClone()
{
return (MyOwnClass)MemberwiseClone();
}
}
MemberwiseClone
继承自System.Object
。
答案 1 :(得分:0)
ListBoxes使用指针,更新要更新标记为“ 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();
答案 2 :(得分:-1)
它显示最后更新的值,因为字符串是引用类型,它将替换更新时所有现有的引用。因此,您需要创建新数组,然后将其作为源添加到列表框中。
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();
}