修改源项目会更改列表项目吗? [重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了修改源项目会更改列表项目吗? [重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

我正在使用C#中的Windows Forms为一个软件编写一个小插件。我需要解析一个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();
}
答案

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();
另一答案

使用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。现在,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);

现在,ListBox中有两个不同的项目。请注意,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

另一答案

它显示最后更新的值,因为字符串是引用类型,它将替换更新时的所有现有引用。因此,您需要创建新数组,然后将其作为源添加到列表框中。

  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();
   }

以上是关于修改源项目会更改列表项目吗? [重复]的主要内容,如果未能解决你的问题,请参考以下文章

单击recyclerview上的项目时的多个数据

方向更改时,片段视图为空

Python基础入门:列表的使用你知道有哪几种方法吗

Python基础入门:列表的使用你知道有哪几种方法吗

Python基础入门:列表的使用你知道有哪几种方法吗

列表中的项目属性从 EF 源更改值 - 有没有办法“分离”它?