Why does List implement IReadOnlyList in .NE

2019-01-08 00:44发布

问题:

Why does List<T> implement IReadOnlyList<T> in .NET 4.5?

List<T> isn't read only...

回答1:

Because List<T> implements all of the necessary methods/properties/etc. (and then some) of IReadOnlyList<T>. An interface is a contract that says "I can do at least these things."

The documentation for IReadOnlyList<T> says it represents a read-only collection of elements.

That's right. There are no mutator methods in that interface. That's what read-only means, right? IReadOnlyList<T> is used in the "typical" (contract) way, not as a marker.



回答2:

Interfaces only describes functionality which will be implemented. It does not describe functionality which will not be implemented. IReadOnlyList is therefor an incorrect interface name, as it cannot dictate that write functionality will not be written.

The methods/functions of describe that you can read the contents of the list. The interface should have been IReadableList instead of IReadOnlyList.



回答3:

The fact that it implements the interface doesn't mean it is read-only. But because it implements the interface you can now pass it to methods that expect an IReadOnlyList<T>. So the way to look at it, is that it implements the read-only list interface...along with some write methods.



回答4:

Implementing an interface isn't the same as "marking" it. List<T> also implements IEnumerable<T>, but that doesn't mean you're limited to simply enumerating it.

They added the read-only interfaces for API creation, not so you could mark your read-only types with an interface. It allows me to use IReadOnlyCollection<T> for arguments when I just want to know the number of elements in the collection without enumerating it, or IReadOnlyList<T> when I need to reference the elements in the collection by their index. This is good for everyone-- I can be specific about what I need from my caller while allowing my caller to use whatever collection type he wants, as long as it meets the minimum standard I set through the argument type.

So I think the more difficult question is, why wouldn't you have List<T> implement IReadOnlyList<T>?



回答5:

IReadOnlyList is a substitute for the concept of "reference immutability", found in C++ but not in C#. The C++ equivalent is:

void func(T const* t) {...}

or exactly equivalent, as some prefer:

void func(const T* t) {...}

It says that the function func does not mutate the object(s) that its argument t references, called the "referent" of t. It says nothing about whether any other code mutates the referent of t, or even can.

So the C# interface is a substitute for a compiler construct. Why C# does not have the concept of reference immutability is an historical question: I think it was a mistake, but it is too late to fix it now. I think providing the interface substitute is good. I have been using an interface exactly the same as IReadOnlyList<> for years, fortunately with another name, IConstList<>. I may replace my use of IConstList<> with IReadOnlyList<>.



回答6:

The interfaces IReadOnlyList and IReadOnlyCollection are somewhat confusing because they do not mean that the collection is read-only, just that read-only access is supported. From the MSDN documentation (scroll down to Remarks)

The content of list elements is not guaranteed to be read-only.

A better name would be IReadable, see Why doesn't generic ICollection implement IReadOnlyCollection in .NET 4.5?. Furthermore, this implies that IList should inherit IReadOnlyList albeit it does not due to backwards compatibility, see Why doesn't IList<T> inherit from IReadOnlyList<T>?.



回答7:

Isn't it true that the code running IReadOnlyList(Of T) calls to an object that implements that interface is usually running the same thread of execution. That prevents the object from being altered by itself, unless its running on a different thread of execution, but for that situation we have synchronization calls to solve that.