Take the 2-minute tour ×

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>

share|improve this question

8 Answers 8

up vote 178 down vote accepted

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;
          s = Console.ReadLine();
          yield return s;
     } while (s != "");

IEnumerable<string> lines = ReadLines();
lines.Add("foo") // so what would this supposed to do??

What you can do, however, is creating 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).

share|improve this answer
Creating an array to add a single value is a bit high on the overhead. It's a bit more re-usable to define an extension method for a single value Concat. –  JaredPar Jul 31 '09 at 2:08
It depends - it may be worth it, but I'm tempted to call it premature optimization unless Concat is called in a loop repeatedly; and if it is, you have bigger problems anyway, because every time you Concat, you get one more layer of enumerator - so by the end of it the single call to MoveNext will result in a chain of calls equal in length to the number of iterations. –  Pavel Minaev Jul 31 '09 at 2:13
@Pavel, heh. Usually it's not the memory overhead of creating the array that bothers me. It's the extra typing that I find annoying :). –  JaredPar Jul 31 '09 at 2:15
So I understand a bit more what IEnumerable does. It should be view only not intend to be modifed. Thank you guys –  ldsenow Jul 31 '09 at 2:19
I had a Connect feature request for syntactic sugar for IEnumerable<T> in C#, including overloading operator+ as Concat (by the way, do you know that in VB, you can index IEnumerable as if it was an array - it uses ElementAt under the hood): connect.microsoft.com/VisualStudio/feedback/…. If we also get two more overloads of Concat to take a single item both on the left and on the right, this would cut down the typing to xs +=x - so go poke Mads (Torgersen) to prioritize this in C# 5.0 :) –  Pavel Minaev Jul 31 '09 at 2:20

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".


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;
share|improve this answer
That's called Concat :) –  Pavel Minaev Jul 31 '09 at 2:01
@Pavel, thanks for pointing that out. Even Concat won't work though because it takes another IEnumerable<T>. I pasted the typical extension method I define in my projects. –  JaredPar Jul 31 '09 at 2:06
I wouldn't call that Add though, because Add on virtually any other .NET type (not just collections) mutates the collection in-place. Maybe With? Or it could even be just another overload of Concat. –  Pavel Minaev Jul 31 '09 at 2:15
I agree Concat overload would probably be a better choice as Add usually implies mutability. –  Dan Abramov Jul 27 '11 at 16:50
What about modifying the body to return e.Concat(Enumerable.Repeat(value,1));? –  Roy Tinker Oct 4 '11 at 1:06

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 implements IEnumerable<T> so you get all the extensions methods that you get with IEnumerable<T> as well.

share|improve this answer
+1 Good explanation. –  Rex M Jul 31 '09 at 2:13

No the IEnumerable doens't support adding items to it.

An 'alternative' you have is.

var List = new List(items);
share|improve this answer
Your suggestion is not the only alternative. For example, ICollection and IList are both reasonable options here. –  Jason Jul 31 '09 at 2:07
But you can't instantiate either. –  pb. Jul 31 '09 at 2:42
Of course you can't instantiate either - they're interfaces. –  Mike Cole Oct 15 '10 at 15:16

A couple short, sweet extension methods on IEnumerable and IEnumerable<T> do it for me:

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

Elegant (well, except for the non-generic versions). Too bad these methods are not in the BCL.

share|improve this answer
The first Prepend method is giving me an error. "'object[]' does not contain a definition for 'Concat' and the best extension method overload 'System.Linq.Enumerable.Concat<TSource>(System.Collections.Generic.IEnumerable<T‌​Source>, System.Collections.Generic.IEnumerable<TSource>)' has some invalid arguments" –  Tim Newton Jul 23 '13 at 14:11
@TimNewton you're doing it wrong. Who knows why, as nobody can tell from that snippet of error code. Protip: always catch the exception and do a ToString() on it, as that captures more error details. I'd guess you didn't include System.Linq; at the top of your file, but who knows? Try figuring it out on your own, create a minimum prototype that exhibits the same error if you can't and then ask for help in a question. –  Will Jul 23 '13 at 14:45
I just copied and pasted the code above. All of them work ok except the Prepend which is giving the error I mentioned. Its not a runtime exception its a compile time exception. –  Tim Newton Jul 23 '13 at 16:32
@TimNewton: I don't know what you're talking about it works perfectly you obviously are mistaken ignore the changes in the edit now I must be on my way, good day, sir. –  Will Jul 23 '13 at 16:40
maybe its something different about our environment. I'm using VS2012 and .NET 4.5. Dont waste anymore time on this I just thought I would point out that there is a problem with the above code, albeit a small one. I've upvoted this answer anyhow as its useful. thanks. –  Tim Newton Jul 23 '13 at 16:49

Not only can you not add items like you state, but if you add an item to a List<T> (or pretty much any other non-read only collection) that you have an existing enumerator for, the enumerator is invalidated (throws InvalidOperationException from then on).

If you are aggregating results from some type of data query, you can use the Concat extension method:

Edit: I originally used the Union extension in the example, which is not really correct. My application uses it extensively to make sure overlapping queries don't duplicate results.

IEnumerable<T> itemsA = ...;
IEnumerable<T> itemsB = ...;
IEnumerable<T> itemsC = ...;
return itemsA.Concat(itemsB).Concat(itemsC);
share|improve this answer

Others have already given great explanations regarding why you can not (and should not!) be able to add items to an IEnumerable. I will only add that if you are looking to continue coding to an interface that represents a collection and want an add method, you should code to ICollection or IList. As an added bonanza, these interfaces implement IEnumerable.

share|improve this answer

you can do this.

//Create IEnumerable    

//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;
share|improve this answer
This question was answered in a more complete fashion 5 years ago. Look at the accepted answer as an example of a good answer to a question. –  pquest Nov 28 at 18:38

Your Answer


