【问题标题】:C# Lists reference with two?C# Lists 参考有两个?
【发布时间】:2015-02-03 17:16:59
【问题描述】:

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

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

List<int> list3 = list1 & list2

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

多个列表的引用。

这可能吗?

【问题讨论】:

    标签: c# list reference


    【解决方案1】:

    不,您不能直接对 List&lt;T&gt; 执行此操作。但是,您可以声明:

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

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

    如果你想要等价但有连接,你可以使用

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

    同样,这将被延迟评估。

    正如 cmets 中所述,这不会暴露 List&lt;T&gt; 所做的所有操作,但如果您只需要从“组合整数”中读取(并且以迭代方式而不是以某种随机访问方式进行),那么它可能就是你所需要的。

    【讨论】:

    • List&lt;T&gt;.AddRange()?
    • @PanagiotisKanavos 这不会提供所请求的语义。
    • 我无法解读 OP 是否想要重复的问题,是否按顺序排列。
    • Jon,假设他只需要操作 IEnumerable&lt;T&gt; 公开,而不是通过 IList&lt;T&gt; 公开的内容
    • 感谢大家快速而有帮助的回答!对不起,我的英语不好,如果有人有问题要理解我。
    【解决方案2】:

    有可能吗?

    不适用于List,因为它是一个静态数据结构——但是您可以使用一个查询,它是两个列表的连接。然后,每当您枚举查询时,它都会显示当前内容:

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

    但是,一旦您将查询具体化为数据结构(通过调用ToListToArray 等),内容就是静态的,并且不会在基础列表之一更新时更新。

    【讨论】:

      【解决方案3】:

      没有。您可以创建自己的自定义类型,该类型公开类似于 List&lt;T&gt; 所做的方法(索引器、AddRemove 方法等),甚至可能实现 IList&lt;T&gt;,但它不会是 @ 987654325@.

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-02
        • 1970-01-01
        • 2016-03-16
        • 1970-01-01
        相关资源
        最近更新 更多