c#列表中的列表——如何使列表中的列表独一无二且不受版本限制
本文关键字:列表 版本 何使 独一无二 | 更新日期: 2023-09-27 18:18:25
这次我遇到了一个c#编程问题:我有一个列表的列表:
List<List<string>> List1
和其中的字符串列表:
List<string> List2
并且,在循环中,我想将List2放入List1,但是,我想更改List2中的值,但是我不想更改插入到List1中的List2中的值。下面是我想做的伪代码的例子(因为我想现在没有人得到我想要的):
List1 <=> ['one', 'two', 'three']
List2[1] <=> List1
List1.clear
List1 <=> ['four', 'five', 'six']
List2[2] <=> List1
但是List1在List2[1]中也改变了——我不想那样!现在的样子:
List2[1] <=> ['four', 'five', 'six']
List2[2] <=> ['four', 'five', 'six']
但是我希望它是:
List2[1] <=> ['one', 'two', 'three']
List2[2] <=> ['four', 'five', 'six']
有什么意义?我想让这些list1保持那个状态,当我把它们插入到List2时的状态。我希望有人能理解这一点,并将帮助我。我知道我在List2中插入了一些List1指针,但怎么做呢?
你想把List1
的副本放到List2
:
List2[1] = List1.ToList();
否则,List1
, List2[1]
和List2[2]
引用相同的列表,因此通过更改一个,您也更改了其他列表
您需要为外部列表中的每个项创建一个新列表。请记住,您是在外部列表中放置对内部列表的引用,而不是复制。
outerList.Add(new List<string>{"one", "two", "three"})
outerList.Add(new List<string>{"four", "five", "six"})
我们理解。List1"变化"的原因是因为List1是一个指向内存中存储其项的位置的指针。所以当你赋值List2[1] = List1时,你只是在创建另一个名为List2[1]的指针,指向内存中的相同位置。
要完成你所说的,你必须在每次通过循环时创建一个新的列表。例如:
List two = new List<List<string>>();
for (int i = 0; i < 5; i++) {
List one = new List<string> {"one" + i, "two" + i, "three" + i};
two.Add(one);
}
在每次通过该循环时,List 1将是一个新对象。最后,列表二将包含这些值:
[["one1"、"two1"、"three1"],["one2"、"two2","three2"),…)
您可以以任何您希望的方式生成值,但我只是展示了一个基于循环计数器使它们动态的示例。
我知道一个答案。当您希望存储列表的副本而不是对原始列表的引用时,您必须执行深度复制类型的操作。深度复制不是框架的一部分。
通过在http://weblogs.asp.net/jeff/archive/2005/11/21/431125.aspx的博客上的评论者"karl"(http://openmymind.net/)加上我自己的编辑来添加到示例中…您可以序列化和反序列化列表,并获得列表的真实副本:
List<string> strings = new List<string>();
// Do something to populate the list
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, strings);
ms.Seek(0, SeekOrigin.Begin);
List<string> copy = (List<string>)bf.Deserialize(ms) ;
ms.Close();
试着翻译这个页面来理解:http://leonelfraga.com/neomatrixtech/?p=412
请注意代码的差异以及在黑盒子中打印的内容。
要实现您想要的结果,您需要存储您想要修改的列表的副本。您可以通过创建一个新列表并手动添加原始列表中的元素,或者使用扩展方法ToList(...)
来实现这一点。这将创建原始列表的副本,该副本将被存储,因此您可以修改原始列表而不影响副本。