• How can I add an item to a IEnumerable<T> collection?


    How can I add an item to a IEnumerable<T> collection?

    My question as title above. For example

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

    but after all it only has 1 item inside. Can we have a method like items.Add(item) like the List<T>?

    评论

    IEnumerable<T> is meant for querying collections only. It is the backbone for the LINQ framework. It is always an abstraction of some other collection such as Collection<T>, List<T>, or Array. The interface only provides a GetEnumerator method that returns an instance of IEnumerator<T> that enables the walking of the extending collection one item at a time. The LINQ extension methods are limited by this interface. IEnumerable<T> is designed to be read only because it may represent an aggregation of parts of multiple collections.
    – Jordan
    Jan 27, 2016 at 16:04
     
     

    回答1

    You cannot, because IEnumerable<T> does not necessarily represent a collection to which items can be added. In fact, it does not necessarily represent a collection at all! For example:

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

    What you can do, however, is create a new IEnumerable object (of unspecified type), which, when enumerated, will provide all items of the old one, plus some of your own. You use Enumerable.Concat for that:

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

    This will not change the array object (you cannot insert items into to arrays, anyway). But it will create a new object that will list all items in the array, and then "Foo". Furthermore, that new object will keep track of changes in the array (i.e. whenever you enumerate it, you'll see the current values of items).

    回答2

    The type IEnumerable<T> does not support such operations. The purpose of the IEnumerable<T> interface is to allow a consumer to view the contents of a collection. Not to modify the values.

    When you do operations like .ToList().Add() you are creating a new List<T> and adding a value to that list. It has no connection to the original list.

    What you can do is use the Add extension method to create a new IEnumerable<T> with the added value.

    items = items.Add("msg2");

    Even in this case it won't modify the original IEnumerable<T> object. This can be verified by holding a reference to it. For example

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

    After this set of operations the variable temp will still only reference an enumerable with a single element "foo" in the set of values while items will reference a different enumerable with values "foo" and "bar".

    EDIT

    I contstantly forget that Add is not a typical extension method on IEnumerable<T> because it's one of the first ones that I end up defining. Here it is

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

    回答3

    Have you considered using ICollection<T> or IList<T> interfaces instead, they exist for the very reason that you want to have an Add method on an IEnumerable<T>.

    IEnumerable<T> is used to 'mark' a type as being...well, enumerable or just a sequence of items without necessarily making any guarantees of whether the real underlying object supports adding/removing of items. Also remember that these interfaces implement IEnumerable<T> so you get all the extensions methods that you get with IEnumerable<T> as well.

    回答4

    In .net Core, there is a method Enumerable.Append that does exactly that.

    The source code of the method is available on GitHub..... The implementation (more sophisticated than the suggestions in other answers) is worth a look :).

    This is not only in core, also the framework 4.7.1 and newer: docs.microsoft.com/en-us/dotnet/api/…
    – sschoof
    May 21, 2019 at 14:23
     
  • 相关阅读:
    jdbc连接Sql server数据库,并查询数据
    HttpClient,post请求,发送json,并接收数据
    SQL SERVER存储过程一
    HttpClient,get请求,发送并接收数据
    工作中操作数据库实例
    存储过程的实例(公司)
    eclipse发布项目后,项目所在的位置
    SQLSERVER存储过程基本语法
    SAXReader解析
    导包
  • 原文地址:https://www.cnblogs.com/chucklu/p/16669555.html
Copyright © 2020-2023  润新知