如何在不克隆的情况下复制 List<T>
Posted
技术标签:
【中文标题】如何在不克隆的情况下复制 List<T>【英文标题】:How to copy a List<T> without cloning 【发布时间】:2012-07-27 03:44:12 【问题描述】:也许我错过了一些微不足道的东西。我有几个List<T>
s,我需要他们的一个大列表,它是所有其他列表的联合。但我确实希望他们在那个大列表中的引用,而不仅仅是值/副本(不像我通常在 SO 上找到的许多问题)。
例如我有这个,
List<string> list1 = new List<string> "a", "b", "c" ;
List<string> list2 = new List<string> "1", "2", "3" ;
var unionList = GetThatList(list1, list2);
假设我在unionList
中得到了我想要的列表,那么这应该会发生:
unionList.Remove("a"); => list1.Remove("a");
unionList.Remove("1"); => list2.Remove("1");
//in other words
//
//unionList.Count = 4;
//list1.Count = 2;
//list2.Count = 2;
为了清楚起见,这通常发生在
unionList = list1; //got the reference copy.
但是我该如何处理第二个列表,list2
添加到unionList
?
我尝试了Add
和AddRange
,但它们显然是克隆而不是复制。
unionList = list1;
unionList.AddRange(list2); //-- error, clones, not copies here.
和
foreach (var item in list2)
unionList.Add(item); //-- error, clones, not copies here.
更新:我想我在问一些毫无意义的问题,并且在语言中本质上是不可能的......
【问题讨论】:
据我所知,“开箱即用”是不可能的。要么您创建自己的集合类型来包装其他集合(但这似乎不必要地复杂),或者您更可能想要重新考虑您的程序。 @KooKiz 是的,我明白了。我当然可以没有它,但我在想一种可能性.. 它似乎不适用于您的情况,但请记住,这取决于您创建列表的数据类型。如果它是 List(of T as Class) 那么默认情况下它将复制引用而不是克隆对象。我认为只有在使用原始类型(或可能的结构)时才会遇到您所描述的问题。 【参考方案1】:我认为不存在任何这样的课程。你可以自己实现它。这是一个开始:
class CombinedLists<T> : IEnumerable<T> // Add more interfaces here.
// Maybe IList<T>, but how should it work?
private List<List<T>> lists = new List<List<T>>();
public void AddList(List<T> list)
lists.Add(list);
public IEnumerator<T> GetEnumerator()
return lists.SelectMany(x => x).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
return GetEnumerator();
public bool Remove(T t)
foreach (List<T> list in lists)
if (list.Remove(t)) return true;
return false;
// Implement the other methods.
这里有一些代码可以用来测试它:
List<string> list1 = new List<string> "a", "b", "c" ;
List<string> list2 = new List<string> "1", "2", "3" ;
CombinedLists<string> c = new CombinedLists<string>();
c.AddList(list1);
c.AddList(list2);
c.Remove("a");
c.Remove("1");
foreach (var x in c) Console.WriteLine(x);
Console.WriteLine(list1.Count);
Console.WriteLine(list2.Count);
删除项目相当简单。但是,如果您尝试将项目插入组合列表中,您可能会遇到问题。并不总是明确定义哪个列表应该接收插入的项目。例如,如果您有一个包含两个空列表的组合列表,并且您在索引 0 处插入一个项目,该项目应该添加到第一个还是第二个空列表中?
【讨论】:
@nawfal 我很好奇。如果要添加项目怎么办? @KendallFrey,我还没有考虑过。事实上,我自己的问题也是出于好奇而不是要求。但是,是的,如果您添加到较小的列表中,我希望它会添加到 unionlist。但是,如果将其添加到 unionlist,那么正确的选择是在子列表中忽略它。马克的回答是这样处理的,因为 publicAdd
方法没有定义:D
@MarkByers,更加好奇,如果我必须将项目添加到子列表中会怎样?有没有办法反映在 unionlist 中?
@nawfal:如果您将项目添加到子列表中,它将在联合列表中可用。但问题是,如果您尝试将元素直接添加到联合列表中。如果有的话,它应该出现在哪个子列表中?
@nawfal:密钥是SelectMany
。以上是关于如何在不克隆的情况下复制 List<T>的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 JSON.stringify 或 JSON.parse 的情况下在 javascript 中克隆数组? [复制]
如何在不调用渲染函数的情况下访问 Context 的值? [复制]