2

I'm using an API where I'm implementing an interface that has a method returning an IEnumerable.

I'm building the collection in my implementation as a List, because I need the .Add() method.

Can I then convert this to IEnumerable?

Grant Thomas
  • 44,454
  • 10
  • 85
  • 129
Davo
  • 71
  • 1
  • 1
  • 3

2 Answers2

9

Since List<T> implements both IEnumerable<T> and IEnumerable, if you just need it as a return value of a method, you can just return it, e.g:

public IEnumerable<string> GetData()
{
    List<string> myList = new List<string>{" data"};
    return myList; //works
}

what you get on the other side, when you call the method, will be an IEnumerable<T> reference that points to a List<T> object.

That means that the user can use the result wherever he can use an IEnumerable<T>, but also that a simple cast can expose the inner List<T> thus allowing modifications of the data. e.g:

IEnumerable<string> result = GetData();
Console.Write(result.First()); // " data";

List<string> resultAsList = (result as List<string>);
resultAsList.Insert(0, "other data");

Console.Write(result.First()); // "other data";

If you want the result not to be changed, you can use the .AsReadOnly method, to return a ReadOnlyCollection<T> that is still an IEnumerable<T>, like this:

public IEnumerable<string> GetData()
{
    List<string> myList = new List<string>{" data"};
    return myList.AsReadOnly();
}
SWeko
  • 30,434
  • 10
  • 71
  • 106
  • +1 for `AsReadOnly()`. – Rohit Vats Aug 20 '13 at 08:02
  • 1
    The user shouldn't be casting to a List because that's not what the api exposed. It would cause brittle code. If the end user should need IList functionality, then the api should return an IList. – aaaaaa Sep 20 '17 at 02:52
  • 1
    Casting an `IEnumerable` to a modifiable data structure is by itself extremely brittle code :) – SWeko Sep 25 '17 at 09:14
6

As Sweko mentioned you can simply return list but in case you don't want the list to be modified from outside, you can call AsEnumerable on your list to expose IEnumerable outside.

public IEnumerable<string> GetData()
{
   List<string> yourList = new List<string>();
   return yourlist.AsEnumerable();
}
Community
  • 1
  • 1
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • That doesn't really serve any purpose in this case if the method is returning type `IEnumerable` anyway. – Matthew Watson Aug 20 '13 at 07:53
  • @Rohit Not really. Since `AsEnumerable` only changes the type of the reference (and that is already done by the return statement), a simple `(result as List).Add(...)` will work around that. – SWeko Aug 20 '13 at 07:53
  • @Sweko - Yeah you are right. I completely overlook that. – Rohit Vats Aug 20 '13 at 08:00