c# - 修改源项目会更改列表项目?
问题描述
我正在为使用 C# 中的 Windows 窗体的软件编写一个小插件。我需要解析一个 XML 文件来检索一些对象并将它们添加到ListBox
. 问题是在我的程序结束时,所有对象都与最后添加的对象相同。我有点想通为什么,但我仍在寻找如何解决它。这是一个用 aString[]
而不是我的对象的小例子:
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();
}
解决方案
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);
- 创建并初始化一个数组。
- 该数组作为一个项目添加到 ListBox。请注意,数组是引用类型。实际上,您只是添加了对 ListBox 的引用,而不是数组的副本。
- 改变了数组的一个元素。这也会影响添加到 ListBox 的第一项,因为它包含对这个唯一数组的引用。
- 相同的数组引用作为项目添加到 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 方法会创建一个浅克隆。即数组元素本身没有被克隆。因此,如果它们是引用类型,则两个数组将在克隆后包含相同的对象。但是由于您有 2 个不同的数组,您可以替换数组的元素而不影响另一个数组。
您可以将克隆方法添加到您自己的类中
public class MyOwnClass
{
public string Prop1 { get; set; }
public int Prop2 { get; set; }
public MyOwnClass ShallowClone()
{
return (MyOwnClass)MemberwiseClone();
}
}
MemberwiseClone
继承自System.Object
。
推荐阅读
- angular-material - 在angualar 8中,取数据到表的性能有什么提升
- python - 使用 apache(在 unix 上)部署 django(windows)
- mysql - 如何对 mySQL 的结果进行分组
- mysql - MySQL获取每天的最早记录
- node.js - .indexOf 未在 node.js 上返回预期值
- mongodb - 如何找出为什么 MongoDB 会消耗这么多内存?
- java - 我的循环没有执行特定的迭代
- php - 从多键多维数组中提取单个索引值(从每个子数组中)
- gnuplot - 如何在gnuplot中应用tail命令
- java - 在 Java JDBC 中使用动态 where 子句