Perhaps I am missing something trivial. I have a couple of List<T>
s and I need one big list from them which is a union of all the other lists. But I do want their references in that big list and not just the values/copies (unlike many questions I typically find on SO).
For example I have this,
List<string> list1 = new List<string> { "a", "b", "c" };
List<string> list2 = new List<string> { "1", "2", "3" };
var unionList = GetThatList(list1, list2);
Suppose I get the list I want in unionList
, then this should happen:
unionList.Remove("a"); => list1.Remove("a");
unionList.Remove("1"); => list2.Remove("1");
//in other words
//
//unionList.Count = 4;
//list1.Count = 2;
//list2.Count = 2;
To make it clear, this typically happens with
unionList = list1; //got the reference copy.
But how do I go about with the second list, list2
to add to unionList
?
I tried Add
and AddRange
but they obviously clone and not copy.
unionList = list1;
unionList.AddRange(list2); //-- error, clones, not copies here.
and
foreach (var item in list2)
{
unionList.Add(item); //-- error, clones, not copies here.
}
Update: I think I am asking something that makes no sense, and something that inherently is not possible in the language..
I don't think any such class exists. You could implement it yourself. Here's a start:
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.
}
Here's some code you can use to test it:
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);
Removing items is fairly simple. But you might get problems if you try to insert items into your combined list. It is not always well-defined which list should receive the inserted items. For example, if you have a combined list that contains two empty lists and you insert an item at index 0, should the item be added to the first or the second empty list?