3

Usually my methods are as the following:

public List<int> Method1(int input)
{
    var output = new List<int>();
    //add some items to output
    return output;
}

But FxCop advises another IList implementation instead of List, but I can't remember which. The alternatives include returning it as an IList, ICollection or IEnumerable for more flexibility or a whole different way as the code below.:

public int[] Method2(int input)
{
    var output = new List<int>();
    //add some items to output
    return output.ToArray();
}

Of all alternatives, all provided and all possibilities, which is considered the best practice?

Jader Dias
  • 88,211
  • 155
  • 421
  • 625

9 Answers9

6

IEnumerable / IEnumerable <T> unless you specifically need a list, then you should return IList <T>

Surgical Coder
  • 1,086
  • 1
  • 16
  • 25
  • I agree, but can you expand on why? – mmcdole Feb 20 '09 at 15:55
  • Because it allows you to change implementation details inside the function, if needed, without breaking code that calls the function. – Joel Coehoorn Feb 20 '09 at 16:04
  • For example, maybe right now you actually return an array, but at some point in the future you update the code to return a List instead. If all you promised is that you're returning IEnumerable, the calling code will still work just fine. – Joel Coehoorn Feb 20 '09 at 16:05
5

"Framework Design Guidelines" (2nd ed) in §8.3.1 has quite a lot to say about collections as return values, summary:

  • DO NOT provide settable collection properties.
  • DO use Collection<T> or a subclass of Collection<T> for properties or return values representing read/write collections.
  • DO use 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>).

Richard
  • 106,783
  • 21
  • 203
  • 265
5

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>.

AwesomeTown
  • 2,800
  • 2
  • 27
  • 41
3

ReadOnlyCollection<T> is another option.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
2

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.

Inferis
  • 4,582
  • 5
  • 37
  • 47
1

It depends.

Do you want the caller to be able to modify the items and for you to see those changes? Arrays can be modified. The IList interface defines methods for modification (but the implementation may not allow it).

Can you elaborate on the FxCop warning?

Kent

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
  • FxCop recommends you return a ReadOnlyCollection instead of List – Jader Dias Feb 20 '09 at 16:03
  • That seems . . . odd. Like I said, what if you actually want callers to be able to modify the contents? – Kent Boogaart Feb 20 '09 at 16:04
  • "Do not expose List in object models. Use Collection,ReadOnlyCollection or KeyedCollection instead. List is meant to be used from implementation, not in object model API. List is optimized for performance at the cost of long term versioning. .... – Jader Dias Feb 20 '09 at 16:09
  • ... For example, if you return List to the client code, you will not ever be able to receive notifications when client code modifies the collection." – Jader Dias Feb 20 '09 at 16:09
  • That's in CA1002 DoNotExposeGenericLists (Design Rules). Help : http://msdn2.microsoft.com/ms182142(VS.90).aspx – Jader Dias Feb 20 '09 at 16:11
1

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.

Cerebrus
  • 25,615
  • 8
  • 56
  • 70
1

I almost always go with List because it gives me methods that I frequently find the most useful.

One potential negative consequence of returning an IEnumerable is that any exceptions that get thrown upon enumeration would come from an area of code that could be quite far away from the code that actually built the object, making bug tracking harder.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
  • List is handy pre-LINQ for things like "Find", but post-3.5 doesn't give you anything you can't get from the standard IEnumerable extension methods. – AwesomeTown Feb 20 '09 at 16:06
0

Some exponential or polynomial algorithms have many values inside of them you want to extract without adding multiple duplicate methods that just return those separate values. Instead just return new int[] { log n, x^n, residue }.

You can create multiple methods to facade; but you only need the one algorithm to do the work. It is better if it's not recursive too.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 07 '23 at 16:45