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指针,但怎么做呢?

c#列表中的列表——如何使列表中的列表独一无二且不受版本限制

你想把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(...)来实现这一点。这将创建原始列表的副本,该副本将被存储,因此您可以修改原始列表而不影响副本。