[英]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.