繁体   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