Why use IList or List?

后端 未结 10 671
离开以前
离开以前 2020-11-29 15:58

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

相关标签:
10条回答
  • 2020-11-29 16:41

    There are three questions here: what type should I use for a formal parameter? What should I use for a local variable? and what should I use for a return type?

    Formal parameters:

    The principle here is do not ask for more than you need. IEnumerable<T> communicates "I need to get the elements of this sequence from beginning to end". IList<T> communicates "I need to get and set the elements of this sequence in arbitrary order". List<T> communicates "I need to get and set the elements of this sequence in arbitrary order and I only accept lists; I do not accept arrays."

    By asking for more than you need, you (1) make the caller do unnecessary work to satisfy your unnecessary demands, and (2) communicate falsehoods to the reader. Ask only for what you're going to use. That way if the caller has a sequence, they don't need to call ToList on it to satisfy your demand.

    Local variables:

    Use whatever you want. It's your method. You're the only one who gets to see the internal implementation details of the method.

    Return type:

    Same principle as before, reversed. Offer the bare minimum that your caller requires. If the caller only requires the ability to enumerate the sequence, only give them an IEnumerable<T>.

    0 讨论(0)
  • 2020-11-29 16:41

    Using IList instead of List makes writing unit tests significantly easier. It allows you to use a 'Mocking' library to pass and return data.

    The other general reason for using interfaces is to expose the minimum amount of knowledge necessary to the user of an object.

    Consider the (contrived) case where I have a data object that implements IList.

    public class MyDataObject : IList<int>
    {
        public void Method1()
        {
           ...
        }
        // etc
    }
    

    Your functions above only care about being able to iterate over a list. Ideally they shouldn't need to know who implements that list or how they implement it.

    In your example, IEnumerable is a better choice as you thought.

    0 讨论(0)
  • 2020-11-29 16:42

    Inside the method, you should use var, instead of IList or List. When your data source changes to come from a method instead, your onlySomeInts method will survive.

    The reason to use IList instead of List as parameters, is because many things implement IList (List and [], as two examples), but only one thing implements List. It's more flexible to code to the interface.

    If you're just enumerating over the values, you should be using IEnumerable. Every type of datatype that can hold more than one value implements IEnumerable (or should) and makes your method hugely flexible.

    0 讨论(0)
  • 2020-11-29 16:44

    It is always a good idea to reduce the dependencies between your code as much as possible.

    Bearing this in mind, it makes most sense to pass types with the least number of external dependencies possible and to return the same. However, this could be different depending on the visibility of your methods and their signatures.

    If your methods form part of an interface, the methods will need to be defined using types available to that interface. Concrete types will probably not be available to interfaces, so they would have to return non-concrete types. You would want to do this if you were creating a framework, for example.

    However, if you are not writing a framework, it may be advantageous to pass parameter with the weakest possible types (i.e. base classes, interfaces, or even delegates) and return concrete types. That gives the caller the ability to do as much as possible with the returned object, even if it is cast as an interface. However, this makes the method more fragile, as any change to the returned object type may break the calling code. In practice though, that generally isn't a major problem.

    0 讨论(0)
提交回复
热议问题