首页 文章

如何将项添加到IEnumerable <T>集合中?

提问于
浏览
339

我的问题如上所述 . 例如,

IEnumerable<T> items = new T[]{new T("msg")};
items.ToList().Add(new T("msg2"));

但毕竟它里面只有1个项目 .

我们可以有像 items.Add(item) 这样的方法吗?

喜欢 List<T>

13 回答

  • 10

    其他人已经给出了很好的解释,为什么你不能(而且不应该!)能够将项目添加到 IEnumerable . 我只想补充一点,如果您希望继续编写代表集合的接口并想要一个add方法,那么您应该编写为ICollectionIList . 作为一个额外的富矿,这些接口实现 IEnumerable .

  • 46

    我只是来这里说,除了 Enumerable.Concat 扩展方法之外,.NET Core 1.1.1中似乎还有另一个名为 Enumerable.Append 的方法 . 后者允许您将单个项目连接到现有序列 . 所以Aamol的答案也可以写成

    IEnumerable<T> items = new T[]{new T("msg")};
    items = items.Append(new T("msg2"));
    

    不过,请注意,此函数不会更改输入序列,它只返回一个将给定序列和附加项放在一起的包装器 .

  • 1

    你可以做这个 .

    //Create IEnumerable    
    IEnumerable<T> items = new T[]{new T("msg")};
    
    //Convert to list.
    List<T> list = items.ToList();
    
    //Add new item to list.
    list.add(new T("msg2"));
    
    //Cast list to IEnumerable
    items = (IEnumerable<T>)items;
    
  • -8

    最简单的方法就是这样做

    IEnumerable<T> items = new T[]{new T("msg")};
    List<string> itemsList = new List<string>();
    itemsList.AddRange(items.Select(y => y.ToString()));
    itemsList.Add("msg2");
    

    然后你可以将列表作为IEnumerable返回,因为它实现了IEnumerable接口

  • 14

    当然,你可以(我将你的T-business留在一边):

    public IEnumerable<string> tryAdd(IEnumerable<string> items)
    {
        List<string> list = items.ToList();
        string obj = "";
        list.Add(obj);
    
        return list.Select(i => i);
    }
    
  • 28

    你不能,因为 IEnumerable<T> 不一定代表可以添加项目的集合 . 事实上,它并不一定代表一个集合!例如:

    IEnumerable<string> ReadLines()
    {
         string s;
         do
         {
              s = Console.ReadLine();
              yield return s;
         } while (s != "");
    }
    
    IEnumerable<string> lines = ReadLines();
    lines.Add("foo") // so what is this supposed to do??
    

    但是,您可以创建一个新的 IEnumerable 对象(未指定类型),当枚举时,它将提供旧项目的所有项目,以及您自己的一些项目 . 你使用 Enumerable.Concat

    items = items.Concat(new[] { "foo" });
    

    这不会更改数组对象(无论如何都不能将项插入到数组中) . 但它会创建一个新对象,列出数组中的所有项目,然后"Foo" . 此外,该新对象将跟踪数组中的更改(即,只要您枚举它,您将看到项的当前值) .

  • 8

    IEnumerable<T> 类型不支持此类操作 . IEnumerable<T> 界面的目的是允许消费者查看集合的内容 . 不要修改值 .

    当您执行.ToList() . Add()等操作时,您将创建一个新的 List<T> 并向该列表添加一个值 . 它与原始列表没有任何关联 .

    您可以使用添加扩展方法创建具有附加值的新 IEnumerable<T> .

    items = items.Add("msg2");
    

    即使在这种情况下,它也不会修改原始的 IEnumerable<T> 对象 . 这可以通过保持对它的引用来验证 . 例如

    var items = new string[]{"foo"};
    var temp = items;
    items = items.Add("bar");
    

    在这组操作之后,变量temp仍将仅引用具有值集合中的单个元素“foo”的可枚举,而项目将引用具有值“foo”和“bar”的不同可枚举 .

    EDIT

    我不断忘记Add不是 IEnumerable<T> 上的典型扩展方法,因为它是我最终定义的第一个扩展方法之一 . 这里是

    public static IEnumerable<T> Add<T>(this IEnumerable<T> e, T value) {
      foreach ( var cur in e) {
        yield return cur;
      }
      yield return value;
    }
    
  • 7

    您是否考虑使用ICollection<T>IList<T>接口,它们的存在是因为您希望在IEnumerable <T>上使用'Add'方法 . IEnumerable <T>用于'mark'类型为......井......可枚举或只是一系列项目,而不必保证真实底层对象是否支持添加/删除项目 . 还要记住,这些接口实现了IEnumerable <T>,因此您获得了使用IEnumerable <T>获得的所有扩展方法 .

  • 80

    IEnumerableIEnumerable<T> 上的几个简短,甜蜜的扩展方法为我做了:

    public static IEnumerable Append(this IEnumerable first, params object[] second)
    {
        return first.OfType<object>().Concat(second);
    }
    public static IEnumerable<T> Append<T>(this IEnumerable<T> first, params T[] second)
    {
        return first.Concat(second);
    }   
    public static IEnumerable Prepend(this IEnumerable first, params object[] second)
    {
        return second.Concat(first.OfType<object>());
    }
    public static IEnumerable<T> Prepend<T>(this IEnumerable<T> first, params T[] second)
    {
        return second.Concat(first);
    }
    

    优雅(嗯,非通用版本除外) . 太糟糕了,这些方法都不在BCL中 .

  • 0

    没有IEnumerable不支持向其添加项目 .

    你'另类'是:

    var List = new List(items);
    List.Add(otherItem);
    
  • 4

    要添加第二条消息,您需要 -

    IEnumerable<T> items = new T[]{new T("msg")};
    items = items.Concat(new[] {new T("msg2")})
    
  • 4

    您不仅可以添加像您所说的项目,而且如果您将项目添加到 List<T> (或几乎任何其他非只读集合),您有一个现有的枚举器,则枚举器将失效(从那时起抛出 InvalidOperationException ) ) .

    如果要汇总某些类型的数据查询的结果,可以使用 Concat 扩展方法:

    编辑:我最初在示例中使用了 Union 扩展名,这不是很正确 . 我的应用程序广泛使用它来确保重叠查询不会重复结果 .

    IEnumerable<T> itemsA = ...;
    IEnumerable<T> itemsB = ...;
    IEnumerable<T> itemsC = ...;
    return itemsA.Concat(itemsB).Concat(itemsC);
    
  • 401

    在.net Core中,有一个方法 Enumerable.Append 就是这样做的 .

    该方法的源代码是available on GitHub. ....实现(比其他答案中的建议更复杂)值得一看:) .

相关问题