I know there has been a lot of posts on this but it still confuses me why should you pass in an interface like IList and return an interface like IList back instead of the c
Here's an example: I had a project once where our lists got very large, and resulting fragmentation of the large object heap was hurting performance. We replaced List with LinkedList. LinkedList does not contain an array, so all of a sudden, we had almost no use of the large object heap.
Mostly, we used the lists as IEnumerable, anyway, so there was no further change needed. (And yes, I would recommend declaring references as IEnumerable if all you're doing is enumerating them.) In a couple of places, we needed the list indexer, so we wrote an inefficient IList wrapper around the linked lists. We needed the list indexer infrequently, so the inefficiency was not a problem. If it had been, we could have provided some other implementation of IList, perhaps as a collection of small-enough arrays, that would have been more efficiently indexable while also avoiding large objects.
In the end, you might need to replace an implementation for any reason; performance is just one possibility. Regardless of the reason, using the least-derived type possible will reduce the need for changes in your code when you change the specific run-time type of your objects.