In my understanding we use interfaces to let the user also use custom list(which need to implement the IList for example).
In many code exercises I see something like this.
IList<string> interfaceList = new List<string>();
My question is. Isn't the following list as capable as the first one since both get implemented by List. If yes why use IList when not using custom Lists?
List<string> normalList = new List<string>();
CodePudding user response:
Isn't the following list as capable as the first one
It is as there is no difference between the LISTS - both are crated with the same statement.
The only difference is in the type of VARIABLE HOLDING THE REFERENCE - not the list itself (which is in both cases a List.
It is a matter of style - using IList allows you to easier replace the list with another type implementing IList.
That being said, depending on USAGE you may find out that List is not JUST an IList but also defines OTHER methods. Hence the use of IList may actually be impossible.
Also note that practically for the vast majority of cases it makes no difference - MOST variables will be small and local in use. As such, arguments like "dynamically injecting another type" etc. are irrelevant - there simply is not enough visibility to even mock the created type. Simply as most variables are local.
CodePudding user response:
Whilst IList<>
may implement all the functionality that List<>
does, I would generally recommend against IList<>
at all, and suggest you use either IEnumerable<>
or ICollection<>
instead.
IEnumerable<>
for collections that don't require modification, and ICollection<>
for collections that you are allowed to modify.
Doing this allows you to swap out the implementation for a more efficient one, just at the point of creation, rather than having to modify every function that references the collection.
Imagine you decide to change a List<>
to HashSet<>
. If your code uses IList<>
then every reference will have to change, whereas, using IEnumerable<>
would mean you only make 1 change.
CodePudding user response:
To answer shortly and concisely your excellent question, the answer is No. But it is important to understand the reason for it, because this understanding opens the door for abstract thinking. It all boils down to the abstract.
In programming you want to solve as many types of issues as possible with a code as short as possible.
As a result, you need to have data structures that are specific-enough, but as far as that need is met, you should strongly prefer to generalize the solution AMAP.
All List
objects are also IList
, but not all objects that are IList
are also List
.
So, if your code assumes that your object is a List
, then it necessarily supports far less cases than if you would be more agnostic and would say that it is an IList
.
If IList
properly describes all the methods you might possibly want to call, then it is specific-enough to solve your problem, so it is good. Now, let's suppose that you need to implement a method that searches for an item insidea list. If you implement it so as the parameter it expects is an instance of List
, then your method will not work for any objects that are IList
, but not List
. So, a decision to declare something as a List
instead of IList
should always be some strong argument, like, for some well-understood reason, you do not want to support any other IList
, or something that List
is capable of but IList
is not capable of is needed by the source-code section in question.
CodePudding user response:
IList also allows you to mock it in a unit test.