Usually my methods are as the following:
public List Method1(int input)
{
var output = new List();
//add some items to output
IEnumerable / IEnumerable <T> unless you specifically need a list, then you should return IList <T>
Return the interface that you need in the code calling this method.
If you need to do list actions on the result, return IList<T>
.
If you just need to enumerate the results, return IEnumerable<T>
.
Those are the ones I use most, actually. I never return arrays from public interfaces unless there's a very good reason for it.
Eric Lippert has a good post on why returning an array is usually a bad idea.
Typically, you should be as general as you can be without causing undue grief to whoever is going to be calling your method. Prefer interfaces over concrete classes, and pick the most generic interface you can get away with.
Returning interfaces better encapsulates your implementation, and will make things easier to change in the future. If you start with a concrete type, you're committed to always returning that type.
IEnumerable<T>
is the best place to start. With the advent of LINQ, there are very few things a caller can't do easily just given an enumeration. If a caller occasionally needs a list, it's easy enough to call .ToList()
.
If callers are likely to have a specific need to index into the returned collection, or if they are likely going to want to modify the collection themselves (inserting/removing/reordering items), consider using an IList<T>
.
It depends on your requirement. All things said and done, iteration through strongly typed arrays is the fastest amongst all collection types. If you do not need to resize/add/search through them, arrays are quite fine.
ReadOnlyCollection<T>
is another option.
"Framework Design Guidelines" (2nd ed) in §8.3.1 has quite a lot to say about collections as return values, summary:
Collection<T>
or a subclass of Collection<T>
for properties or return values representing read/write collections. ReadOnlyCollection<T>
, a subclass of ReadOnlyCollection<T>
, or in rare cases IEnumerable<T>
for properties or return values representing read-only collections. (and more, but these three capture the core).
The first of those above: don't return reference to internal collection unless you want the user to be able to change it (and then likely you should have a custom type so you have a degree of control).
I would return IList<T>
and ensure I do not define the actual type I am returning, unless I was returning an iterator (when I would use IEnumerable<T>
).