Reputation: 19937
I'm designing a class with several functions returning lists of objects. I noticed that debugging becomes easier when my IEnumerable<T>
is converted to a List<T>
since the objects can be viewed in the Watch window. However, I'm not sure if this is best practice when it comes to IEnumerable
.
Q: Which is better?
public IEnumerable<MyData> GetData()
{
return Foo();
}
public IEnumerable<MyData> GetData()
{
return Foo().ToList();
}
Upvotes: 4
Views: 1008
Reputation: 12226
There is a simple rule: return more concrette, accept more generic.
If your return value is really IEnumerable<>
then return it as it is. But never do that:
public IEnumerable<MyData> GetData()
{
return this.list; // list = new List<MyData>();
}
Code above limits caller without any need. It will be a list and caller anyway will be able to cast it to list and clear it for example.
Upvotes: 0
Reputation: 100527
Good practice - don't do work unless there are good reasons/required. So unless you have special reasons - just return IEnumerable<MyData>
without calling ToList()/ToArray() on it.
Potential reasons:
Upvotes: 5
Reputation: 15015
IEnumerable<T>
is offering the caller a contract of a collection of T. However, when you use IList<T>
or List<T>
, you are suggesting that they can add or remove elements directly (without going through any methods such as Add or Register you may have in your class implementation). If your intent is simply to allow the caller to see the 'items', IEnumerable is the better contract.
Whilst it isn't 100%, I see IEnumerable return values as read-only collections.
Ease of debugging should be secondary to good design. I would recommend that you simply unit-test your class rather than rely on being able to peek inside at runtime. However, in most cases, the debugger shows the 'base' class as the first item. So the IEnumerable's first item is the List you're actually using internally. It only takes one more 'expand' to see the members!
Upvotes: 1
Reputation: 15130
It really depends on your requirements. The return type of a the method signature is also part of the contract of that method. A method returning an IEnumerable indicates a stream of values while a method returning a List (or more abstract, a Collection) returns a mutable collection of values.
I normally try to keep up with the following practices.
Upvotes: 1
Reputation: 62248
Better return IEnumerable<..>
as more generic type. After caller can decide what to do with it. In your case you return IEnumerable<..>
in both cases, so there is no any reason run ToLIst()
, just return IEnumerable
Upvotes: 2
Reputation: 1985
Returning IEnumerable lets the caller decide what to do with the results - either enumerate it or pass it on to something else without enumerating it at the current moment. ToList() forces the data to be enumerated at this point, into a list which is then passed on to the caller.
Therefore - IEnumerable would most likely be the better of the two - however it can be easier to use ToList when debugging.
Upvotes: 0
Reputation: 5801
I'ts better to use a list of elements in case you are using a unit of work that will be disposed, because once its disposed you will not be able to get your elements after.
In all other cases its ok to return the generic IEnumerable, because it offers better flexibility.
In the end it all comes down to your requirements, note that IEnumnerable does not retrieve the elements at the exact moment of assignment to a variale but rather when enumerated.
Upvotes: 1