26

I have a method:

static void FileChangesDetected(List<ChangedFiles> files)

I used Visual Studio 2010 and Resharper. Resharper always recommends that I change the List<T> to IEnumerable<T>, and I'm wondering why this is.

In the method, I simply do this:

 foreach (var file in files)
 { ... }

Is there a benefit of using IEnumerable<T> rather than List<T>?

thirtydot
  • 224,678
  • 48
  • 389
  • 349
Craig
  • 18,074
  • 38
  • 147
  • 248

5 Answers5

29

It all has to do with LSP (Liskov substitution principle).

Basically, instead of using implementations, it is better to code to abstractions.

In this specific case, if all you do is loop over the list, you can use IEnumerable<T> as the simplest abstraction - this way you don't have to use a List<T>, but any collection type in your function.

This allows your functions to be more reusable and reduces coupling.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • IEnumerable is simpler than ICollection – Achim May 28 '11 at 07:42
  • IEnumerable, not ICollection. – Peter Lillevold May 28 '11 at 07:43
  • Thanks. Is it because using IEnumerable/ICollection uses less system resource, or is more efficient than using List<>, because List<> provides more methods, which I am not using? – Craig May 28 '11 at 07:47
  • 3
    @cdotlister - It has nothing to do with resources, but with software design. It is better _design_. – Oded May 28 '11 at 07:48
  • @cdolister - For instance, say I already have have a (old school, or just not-so-well-designed) library method which returns an array... which IS IEnumerable, but IS NOT a List... so I could pass it your useful `FastForward(IEnumerable – corlettk May 28 '11 at 07:57
  • Sorry to be picky, but Liskov does not stipulate that you should or must substituate the supertype wherever possible, it just says that it should *always* be possible. There is no notion of such an advice as "it's better to use abstraction" in Liskov. What is true, though, is, if your code follows Liskov principle, then you can apply this R# recommendation safely. – Simon Mourier Jun 29 '11 at 06:01
3

Resharper suggests that your method doesn't need really require List<T> as a parameter and can easily work with IEnumerable<T>. Which means that you can make you method more generic.

Alex Aza
  • 76,499
  • 26
  • 155
  • 134
3

If you are just iterating of your files, then it does not have to be a List<>. Your code would also work with an array. Or more general: It will work with anything you can iterate over. That's expressed by IEnumerable<>. So the usage of List<> restricts the usage of you message without any need. The ReSharper method is just a hint for that.

Achim
  • 15,415
  • 15
  • 80
  • 144
2

Because in your code, you only use the fact that files is an IEnumerable<ChangedFiles>, you don't use for example Count, nor Add.

Even if later on, you want to use List specific methods (with Add or Count methods), it's always better to use an interface: IList<ChangedFiles> instead of a concrete implementation.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
1

You will still be able to the foreach even if you change it to

IEnumerable<ChangedFiles>

or

ICollection<ChangedFiles>
killebytes
  • 940
  • 1
  • 10
  • 24