簡體   English   中英

C#列出兩個參考?

[英]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 ,它將返回list1list2 (或兩者)中的每個整數。 它只會返回任何整數一次。

如果您想要等效但具有連接,則可以使用

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);

但是只要將查詢實現為數據結構(通過調用ToListToArray等),內容就是靜態的,如果其中一個基礎列表更新,則不會更新。

不可以。您可以創建自己的自定義類型,公開類似於List<T> (索引器, AddRemove方法等),甚至可能實現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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM