[英]C# Lists reference with two?
我需要2个单独的列表和一个包含这两个列表的项目的列表。
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
List<int> list3 = list1 & list2
当我在list1中添加一些整数时,我希望它们也出现在list3中。 将新项添加到list2时,我想要相同的行为。
多个列表的引用。
这可能吗?
不,你不能直接用List<T>
做到这一点。 但是,您可以声明:
IEnumerable<int> union = list1.Union(list2);
现在这将被懒惰地评估 - 每次迭代union
,它将返回list1
或list2
(或两者)中的每个整数。 它只会返回任何整数一次。
如果您想要等效但具有连接,则可以使用
IEnumerable<int> concatenation = list1.Concat(list2);
再次,这将被懒惰地评估。
正如注释中所述,这并未公开List<T>
所做的所有操作,但如果您只需要从“组合整数”中读取(并且以迭代方式而不是以某种随机访问方式进行),那么它可能是一切你需要的。
可能吗?
不是List
因为它是一个静态数据结构 - 但是你可以使用一个查询 ,它是两个列表的串联。 然后,每当您枚举查询时,它将显示当前内容:
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
IEnumerable<int> list3 = list1.Concat(list2);
但是只要将查询实现为数据结构(通过调用ToList
, ToArray
等),内容就是静态的,如果其中一个基础列表更新,则不会更新。
不可以。您可以创建自己的自定义类型,公开类似于List<T>
(索引器, Add
, Remove
方法等),甚至可能实现IList<T>
,但它不会是List<T>
。
public class CompositeList<T> : IList<T>
{
private IList<IList<T>> lists;
public CompositeList(IList<IList<T>> lists)
{
this.lists = lists;
}
public CompositeList(params IList<T>[] lists)
{
this.lists = lists;
}
public int IndexOf(T item)
{
int globalIndex = 0;
foreach (var list in lists)
{
var localIndex = list.IndexOf(item);
if (localIndex >= 0)
return globalIndex + localIndex;
else
globalIndex += list.Count;
}
return -1;
}
public void Insert(int index, T item)
{
//note that there is an ambiguity over where items should be inserted
//when they are on the border of a set of lists.
foreach (var list in lists)
{
//use greater than or equal instead of just greater than to have the inserted item
//go in the later of the two lists in ambiguous situations,
//rather than the former.
if (index > list.Count)
index -= list.Count;
else
{
list.Insert(index, item);
return;
}
}
//TODO deal with having no lists in `lists`
//TODO deal with having only empty lists in `lists`
throw new IndexOutOfRangeException();
}
public void RemoveAt(int index)
{
foreach (var list in lists)
{
if (index > lists.Count)
index -= list.Count;
else
list.RemoveAt(index);
}
throw new IndexOutOfRangeException();
}
public T this[int index]
{
get
{
foreach (var list in lists)
{
if (index > lists.Count)
index -= list.Count;
else
return list[index];
}
throw new IndexOutOfRangeException();
}
set
{
foreach (var list in lists)
{
if (index > lists.Count)
index -= list.Count;
else
list[index] = value;
}
throw new IndexOutOfRangeException();
}
}
public void Add(T item)
{
if (!lists.Any())
lists.Add(new List<T>());
lists[lists.Count - 1].Add(item);
}
public void Clear()
{
foreach (var list in lists)
list.Clear();
}
public bool Contains(T item)
{
return lists.Any(list => list.Contains(item));
}
public void CopyTo(T[] array, int arrayIndex)
{
if (array.Length - arrayIndex - Count < 0)
throw new ArgumentException("The array is not large enough.");
int iterations = Math.Min(array.Length, Count);
for (int i = arrayIndex; i < iterations; i++)
array[i] = this[i];
}
public int Count
{
get { return lists.Sum(list => list.Count); }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
foreach (var list in lists)
{
if (list.Remove(item))
return true;
}
return false;
}
public IEnumerator<T> GetEnumerator()
{
return lists.SelectMany(x => x).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.