33

Here's how I would add one item to an IEnumerable object:

//Some IEnumerable<T> object
IEnumerable<string> arr = new string[] { "ABC", "DEF", "GHI" };

//Add one item
arr = arr.Concat(new string[] { "JKL" });

This is awkward. I don't see a method called something like ConcatSingle() however.

Is there a cleaner way to add a single item to an IEnumerable object?

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
user2023861
  • 8,030
  • 9
  • 57
  • 86

6 Answers6

23

Nope, that's about as concise as you'll get using built-in language/framework features.

You could always create an extension method if you prefer:

arr = arr.Append("JKL");
// or
arr = arr.Append("123", "456");
// or
arr = arr.Append("MNO", "PQR", "STU", "VWY", "etc", "...");

// ...

public static class EnumerableExtensions
{
    public static IEnumerable<T> Append<T>(
        this IEnumerable<T> source, params T[] tail)
    {
        return source.Concat(tail);
    }
}
LukeH
  • 263,068
  • 57
  • 365
  • 409
9

IEnumerable is immutable collection, it means you cannot add, or remove item. Instead, you have to create a new collection for this, simply to convert to list to add:

var newCollection = arr.ToList();
newCollection.Add("JKL"); //is your new collection with the item added
Ram
  • 15,908
  • 4
  • 48
  • 41
cuongle
  • 74,024
  • 28
  • 151
  • 206
  • Perhaps I am missing something....but Add does not return the new list....https://msdn.microsoft.com/en-us/library/vstudio/3wcytfd1(v=vs.100).aspx – Joshua Enfield Mar 10 '15 at 21:11
  • `Add` doesn't return the new list but because `List` is a *mutable* collection you can simply reference the `List` object to access the 'new list'. This answer is slightly pedantic in that sense (because it's mostly obvious that the OP was asking how to create a new `IEnumerable` from another `IEnumerable` and one additional object). – Kenny Evitt Aug 26 '15 at 20:57
  • > `IEnumerable` is *immutable* collection -- That's wrong, it is not a collection, it's an interface. An object of a class that implements it may be immutable (like Array) or mutable (like List), this depends on the implementation. – tsul Apr 11 '19 at 10:13
8

Write an extension method ConcatSingle :)

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

But you need to be more careful with your terminology.
You can't add an item to an IEnumerable<T>. Concat creates a new instance.

Example:

var items = Enumerable.Range<int>(1, 10)
Console.WriteLine(items.Count()); // 10
var original= items;
items = items.ConcatSingle(11);
Console.WriteLine(original.Count());   // 10
Console.WriteLine(items.Count()); // 11

As you can see, the original enumeration - which we saved in original didn't change.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
7

Since IEnumerable is read-only, you need to convert to list.

var new_one = arr.ToList().Add("JKL");

Or you can get a extension method like;

public static IEnumerable<T> Append<T>(this IEnumerable<T> source, params T[] item)
{
    return source.Concat(item);
}
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • 1
    `IEnumerable` is read-only. That does not mean it is immutable. An immutable collection is one that will never change. An `IEnumerable` doesn't even promise that the reference can't be typecast to a mutable type, much less that the underlying collection won't change. – supercat Mar 06 '13 at 20:50
3

Append() - is exactly what you need, it has been added to the .NET Standard (in 2017), so you no longer need to write your own extension methods. You can simply do this:

arr = arr.Append("JKL");

Since .NET is open source, here you can look on the implementation (it is more sophisticated than custom methods suggested above): https://github.com/dotnet/runtime/blob/master/src/libraries/System.Linq/src/System/Linq/AppendPrepend.cs

Gregory L
  • 376
  • 3
  • 5
  • Interesting, Thanks. It looks like the new .Net version is attaching linked lists to the beginning and end of the given IEnumerable. – user2023861 Jul 07 '20 at 19:25
2

You're assigning an array to an IEnumerable. Why don't you use the Array type instead of IEnumerable?

Otherwise you can use IList (or List) if you want to change the collection.

I use IEnumerable only for methods params when I need to read and IList (or List) when I need to change items in it.

Caelan
  • 940
  • 1
  • 7
  • 28