C#列出两个参考?

时间:2015-02-03 17:17:00

标签: c# list reference

我需要两个独立的列表和一个包含这两个列表项的列表。

List<int> list1 = new List<int>();
List<int> list2 = new List<int>();

List<int> list3 = list1 & list2

当我在list1中添加一些整数时,我希望它们也出现在list3中。 将新项目添加到list2时,我想要相同的行为。

多个列表的引用。

这可能吗?

3 个答案:

答案 0 :(得分:8)

不,你不能直接用List<T>做到这一点。但是,您可以声明:

IEnumerable<int> union = list1.Union(list2);

现在将进行延迟评估 - 每次迭代union时,它将返回list1list2(或两者)中的每个整数。它只返回任何一次整数。

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

IEnumerable<int> concatenation = list1.Concat(list2);

同样,这将被懒惰地评估。

如注释中所述,这并未公开List<T>所做的所有操作,但是如果您只需要读取“组合整数”(并且以迭代方式而不是以某种随机访问方式进行)那可能就是你所需要的一切。

答案 1 :(得分:2)

  

有可能吗?

不是List,因为它是静态数据结构 - 但是您可以使用查询,它是两个列表的串联。然后,无论何时枚举查询,它都会显示当前内容:

List<int> list1 = new List<int>();
List<int> list2 = new List<int>();

IEnumerable<int> list3 = list1.Concat(list2);

但是只要将查询实现为数据结构(通过调用ToListToArray等),内容就是静态的,如果其中一个基础列表更新,则不会更新。 / p>

答案 2 :(得分:2)

没有。您可以创建自己的自定义类型,公开类似于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();
    }
}