【问题标题】:Code for adding to IEnumerable添加到 IEnumerable 的代码
【发布时间】:2013-03-23 13:20:45
【问题描述】:

我有一个这样的枚举器

IEnumerable<System.Windows.Documents.FixedPage> page;

如何添加页面(例如:D:\newfile.txt)?我尝试过AddAppendConcat 等,但没有任何效果。

【问题讨论】:

  • 你试过Concat?如何?您可以将单个页面包装在一个集合中,例如new[]{singlePage}。然后你可以将它用于Enumerable.Concatvar pages = page.Concat(new[]{singlePage});

标签: c# ienumerable add


【解决方案1】:

是的,有可能

可以将序列(IEnumerables)连接在一起并将连接的结果分配给新序列。 (你不能改变原来的顺序。)

内置的Enumerable.Concat()只会连接另一个序列;但是,很容易编写一个扩展方法,让您将一个标量连接到一个序列。

以下代码演示:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    public class Program
    {
        [STAThread]
        private static void Main()
        {
            var stringList = new List<string> {"One", "Two", "Three"};

            IEnumerable<string> originalSequence = stringList;

            var newSequence = originalSequence.Concat("Four");

            foreach (var text in newSequence)
            {
                Console.WriteLine(text); // Prints "One" "Two" "Three" "Four".
            }
        }
    }

    public static class EnumerableExt
    {
        /// <summary>Concatenates a scalar to a sequence.</summary>
        /// <typeparam name="T">The type of elements in the sequence.</typeparam>
        /// <param name="sequence">a sequence.</param>
        /// <param name="item">The scalar item to concatenate to the sequence.</param>
        /// <returns>A sequence which has the specified item appended to it.</returns>
        /// <remarks>
        /// The standard .Net IEnumerable extensions includes a Concat() operator which concatenates a sequence to another sequence.
        /// However, it does not allow you to concat a scalar to a sequence. This operator provides that ability.
        /// </remarks>

        public static IEnumerable<T> Concat<T>(this IEnumerable<T> sequence, T item)
        {
            return sequence.Concat(new[] { item });
        }
    }
}

【讨论】:

  • 是的,它可能,但它非常效率低下!
  • 澄清一下,它确实将一个项目附加到现有集合中,它会创建一个附加该项目的新序列
  • 可以修改现有的集合。请参阅下面的答案。
【解决方案2】:

IEnumerable&lt;T&gt; 不包含修改集合的方法。

您将需要实现ICollection&lt;T&gt;IList&lt;T&gt;,因为它们包含添加和删除功能。

【讨论】:

    【解决方案3】:

    如果你知道 IEnumerable 的原始类型是什么,你可以修改它...

    List<string> stringList = new List<string>();
    stringList.Add("One");
    stringList.Add("Two");
    IEnumerable<string> stringEnumerable = stringList.AsEnumerable();
    List<string> stringList2 = stringEnumerable as List<string>;
    
    if (stringList2 != null)
        stringList2.Add("Three");
    
    foreach (var s in stringList)
        Console.WriteLine(s);
    

    这个输出:

    One
    Two
    Three
    

    更改 foreach 语句以迭代 stringList2stringEnumerable,您将得到相同的结果。

    反射可能有助于确定 IEnumerable 的 real 类型。

    不过,这可能不是一个好习惯……不管给你 IEnumerable 的东西,都可能不希望以这种方式修改集合。

    【讨论】:

    • 最好将 stringList2 转换为 ICollection 而不是 List,因为它适用于 List 以及从 ICollection 继承的其他对象。如果 stringList 不是 ICollection 它仍然会失败并且不会添加。
    【解决方案4】:

    IEnumerable&lt;T&gt; 是只读接口。您应该改用IList&lt;T&gt;,它提供了添加和删除项目的方法。

    【讨论】:

    • 如果您要使用更具体的界面,我会使用您可以使用的最高级别的界面,即ICollection&lt;T&gt;
    【解决方案5】:

    IEnumerable 是不可变的。您不能添加项目,也不能删除项目。
    System.Collections.Generic 中的类返回此接口,以便您可以迭代集合中包含的项目。

    来自 MSDN

    Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
    

    有关 MSDN 参考,请参阅 here

    【讨论】:

      【解决方案6】:

      试试

      IEnumerable<System.Windows.Documents.FixedPage> page = new List<System.Windows.Documents.FixedPage>(your items list here)
      

      IList<System.Windows.Documents.FixedPage> page = new List<System.Windows.Documents.FixedPage>(1);
      page.Add(your item Here);
      

      【讨论】:

        【解决方案7】:

        您不能向IEnumerable&lt;T&gt; 添加元素,因为它不支持添加操作。您要么必须使用ICollection&lt;T&gt; 的实现,要么尽可能将IEnumerable&lt;T&gt; 转换为ICollection&lt;T&gt;

        IEnumerable<System.Windows.Documents.FixedPage> page;
        ....
        ICollection<System.Windows.Documents.FixedPage> pageCollection 
            = (ICollection<System.Windows.Documents.FixedPage>) page
        

        如果演员是不可能的,使用例如

        ICollection<System.Windows.Documents.FixedPage> pageCollection 
           = new List<System.Windows.Documents.FixedPage>(page);
        

        你可以这样做:

        ICollection<System.Windows.Documents.FixedPage> pageCollection
            = (page as ICollection<System.Windows.Documents.FixedPage>) ??
              new List<System.Windows.Documents.FixedPage>(page);
        

        后者几乎可以保证您拥有一个可修改的集合。不过有可能在使用 cast 时成功获取集合,但所有修改操作都抛出NotSupportedException。对于只读集合来说就是这样。在这种情况下,使用构造函数的方法是唯一的选择。

        ICollection&lt;T&gt; 接口实现了IEnumerable&lt;T&gt;,因此您可以在当前使用page 的任何地方使用pageCollection

        【讨论】:

          猜你喜欢
          • 2013-08-22
          • 2011-06-28
          • 2020-12-07
          • 1970-01-01
          • 2017-02-13
          • 1970-01-01
          • 2013-05-24
          • 1970-01-01
          • 2015-08-25
          相关资源
          最近更新 更多