Why do arrays support IList?

The IList interface requires the Add method. Arrays implement this function, but it just throws a NotImplementedException. I think this is a very bad design.

What did the designers think when they did this?

+6
arrays c # ilist
source share
2 answers

ILists can be read-only - if in doubt, the caller can check the IsFixedSize property before trying to add or remove an element, or the IsReadOnly property before trying to change the element.

An array is an IList with a fixed size.

It may be convenient to be able to treat the array as a list. One example is the mocking data access method that IList returns - you can mock it just to return the array that was passed as IList.

+7
source share

Since different capabilities are characterized by different objects, some interfaces include elements that will be implemented by some, but not all, implementations. If some, but not all, implementations of the hypothetical IVehicle interface could attach a trailer, a typical template would be to define the AttachTrailer function as "Attempt to attach a trailer if CanAttachTrailer true, or throw a NotSupportedException ". All IVehicle implementations could meet the above specification, regardless of whether they can handle trailers.

The advantage of this approach is that interface implementations can offer many different combinations of functions without having to define different types for different combinations. Another advantage of this approach is that the Foo method, which receives an object that includes capabilities that Foo does not need, can be passed to this method along with the Bar method, which really needs these capabilities, without requiring any tricks in anywhere, and without Foo knowing what Bar features would be needed. Another advantage is that it makes it easier to write code that does not need certain features, but can use them when they exist.

However, there are some drawbacks to this approach. There is still no way for the interface to define default specifications for any properties or methods. Therefore, even IVehicle implementations that trailers cannot attach, you will need to include code to return false in the CanAttachTrailer property and throw an exception in your AttachTrailer method. In addition, since the interface does not require many of its methods to be implemented, the compiler cannot know to reject when trying to call a function that requires capabilities with an object of a type that cannot provide it.

When developing IList<T> Microsoft seemed to think that the advantages of the “advanced features interface” interface outweighed the disadvantages. In fact, if .net provided facilities for classes that implement interfaces to delay the default implementation for members that they do not want to provide, there would be little reason not to include many additional features in basic interfaces; in order to be able to compile the necessary capabilities, it would be possible to obtain several interfaces from a database that includes all the necessary members and indicate that classes that implement the latest interfaces should implement certain elements in ways that are really useful. For example, Microsoft could define an IResizableList<T> to inherit IList<T> without adding any members, but with the expectation of implementing IList<T> implementations that allow resizing, it will implement the last interface, while those that do not allow resizing size will not implement it. If they did, code that should have been able to resize the list might require an IResizableList<T> (in this case it would not accept an array), while code that shouldn't resize the list might require IList<T> ), Unfortunately, Microsoft did not do anything like this, so the code cannot require resizing the list at compile time - all it can do is squawk if the list of past messages reports itself as a fixed size.

0
source share

All Articles