7

In C#

IEnumerable<MyModel> test = _blah.tolist();

Now I can loop through test, but how do I add an item?

Please do not tell me that it makes no sense to add an item, I've already seen that post.

What I want to know is, if I loop through 10 items, how do I put one more on so it loops through 11 items?

Also there is no .Add() method

Harshana Narangoda
  • 775
  • 1
  • 8
  • 23
user1854438
  • 1,784
  • 6
  • 24
  • 30
  • 1
    I'm not sure how this is a duplicate. That question is for _concatenation of two `IEnumerables`_ -- it's in the title, even -- and this is to _add a single element_ to a _single_ `IEnumerable`. You'll notice that though one answer, below, is to `Concat`, the accepted answer _that would not work for concatenation_ is to cast to something that does have an `.Add` method. They're different questions. **At the very least**, as I wouldn't be surprised if someone had asked how to add before, **the dupe link is wrong.** – ruffin Feb 09 '22 at 14:19

3 Answers3

12

IEnumerable is an interface. You can't use Add() on an IEnumerable because they're not required to implement an Add() method. See the IEnumerable documentation on MSDN.

Instead, create a generic list which inherits from the interface IList. Types that use the IList interface must implement Add().

List<MyBlahType> test = _blah.tolist();
test.Add(new MyBlahType());

If you still want to use an interface to avoid a concrete type, then use IList directly.

IList<MyBlahType> test= _blah.tolist();
test.Add(new MyBlahType());

By the way, it's usually considered poor styling to start variable/type names with underscores and to not use proper capitalization. The preferred style in C# is to use PascalCase or camelCase for capitalization.

mason
  • 31,774
  • 10
  • 77
  • 121
  • 1
    You absolutely code against interfaces where you can: http://stackoverflow.com/questions/4456424/what-do-programmers-mean-when-they-say-code-against-an-interface-not-an-objec – Jamiec Apr 25 '14 at 15:22
  • 2
    “You don't typically use interfaces directly” – Well, you actually do. You typically want to avoid using concrete types when it’s not necessary to achieve loose coupling. – poke Apr 25 '14 at 15:26
  • I wouldn't be surprised if this question gets an insane amount of downvotes because of your comment about PascalCase being the preferred casing convention for C#. While I agree that PascalCase is the most logical convention, many argue that camelCase is preferred for variables, fields, and return methods. – oscilatingcretin Apr 25 '14 at 15:28
  • @Jamiec You misunderstood what I said. You don't typically create instances of an interface. I didn't say you can't inherit from interfaces. And I didn't say you can't create instances of interfaces. But the generally accepted practice is to use generic list directly instead of IEnumerable. – mason Apr 25 '14 at 15:28
  • @oscilatingcretin I'm giving general styling advice, not trying to spark a debate about the best styling type. In C#, PascalCase is the more common practice. Either way, his question shows that he went all lower case which is generally not considered good practice anywhere. – mason Apr 25 '14 at 15:30
  • How about `IList` or `ICollection`? There's no need to refer to the concrete type – Jamiec Apr 25 '14 at 15:30
  • @Jamiec If you can provide a concrete reason why to **not** refer to the concrete type, feel free to let me know. – mason Apr 25 '14 at 15:32
  • You might want to change it, you might want to unit test it, you might not know the concrete type at compile time. There are tonnes of reasons not to refer to a concrete type. – Jamiec Apr 25 '14 at 15:37
  • @Jamiec I've done so. I almost never use `IList` directly, but apparently [FxCop encourages it](http://stackoverflow.com/questions/17170/when-to-use-ilist-and-when-to-use-list). – mason Apr 25 '14 at 15:43
6

Use LINQ-to-object's Concat to build a new IEnumerable that iterates the first one and then the second one:

IEnumerable<MyModel> test = _blah.tolist();
IEnumerable<MyModel> second = new[] { theItem };
IEnumerable<MyModel> elevenItems = test.Concat(second);
Jacob Krall
  • 28,341
  • 6
  • 66
  • 76
2

If you've called ToList() on an IEnumerable<T>, the return type will be a List<T>. If the type of your variable were List<T> rather than IEnumerable<T>, you would be able to do whatever you wanted to the list you received, including adding items to it, just like you could do with any other list. Note that the newly made list would be "detached" from the original IEnumerable<T>, so that adding, removing, rearranging, or replacing items in one would not affect the other. Note also, however, that a list of mutable-reference-type items does not hold items, but merely identifies them. If one has an IEnumerable<Car> myCars, and the third item is "Car#24601", then myCars.ToList()[2].Color = CarColors.Red; then the third item in the original list (i.e. Car #24601) will be painted red.

supercat
  • 77,689
  • 9
  • 166
  • 211