修改源项目会更改列表项目吗?

时间:2018-09-18 15:19:58

标签: c# winforms listbox

我正在使用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();
}

3 个答案:

答案 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);
  1. 创建并初始化一个数组。
  2. 此数组作为单个项目添加到ListBox。请注意,数组是引用类型。所以的确,您只添加了对ListBox的引用,而不是数组的副本。
  3. 更改了数组的一个元素。这也会影响添加到ListBox的第一个项目,因为它包含对此唯一数组的引用。
  4. 将相同的数组引用作为一项添加到ListBox。现在,列表框包含2个项,它们引用具有相同元素的相同数组。

如果希望项目包含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();
   }