This article is a mirror article of machine translation, please click here to jump to the original article.

View: 19672|Reply: 1

[Source] . .NET The story of the read-only collection interface

[Copy link]
Posted on 2/5/2018 2:28:10 PM | | |
.NET 4.5Two new collection interfaces, IReadOnlyList and IReadOnlyDictionary, have been added. Although these interfaces may seem so mundane on the surface, they reveal quite complex stories about backward compatibility, interoperability, and the role of co-mutability.

IReadOnlyList and IReadOnlyDictionary are two interfaces that .NET developers have always wanted to have. In addition to providing some sense of symmetry (as opposed to writable interfaces), a read-only interface should eliminate the implementation of methods that only throw a NotSupportedException exception and do nothing. All this was not completed due to time constraints.

The next opportunity is in. NET 2.0. This allows Microsoft to retire weakly typed collections and replace them with strongly typed peer collections. However, the base library[1] team once again missed the opportunity to provide a read-only list, as Kit George wrote,

Since we intend to provide a default implementation for the problem you are talking about with Joe, rather than giving an interface, we provide the ReadOnlyCollectionBase base class. However, I can understand why people are reluctant to use it because it is not a strong type. But with the introduction of generics, we now also have ReadOnlyCollection<T>, so that you not only get the same functionality, but also a strong type: great!

Since ReadOnlyCollection <T>is not a sealed class, you can write your own collection at full speed if necessary. Because these collections that we have created for this are adaptable to general needs, we do not plan to introduce interfaces for this same concept.

Krzysztof Cwalina also expressed his opinion on this topic,

Whether this sounds surprising or not, IList and IList <T>are the two interfaces we intend to use for read-only collections. They both have the IsReadOnly boolean property, which should return true when a read-only collection implements this property. The reason we don't want to add a pure read-only interface is that we feel it adds too much unnecessary complexity to the base library. Note that in terms of complexity, we refer to both this new interface and its consumers.

We believe that if the API designer doesn't care about checking the IsReadOnly property at runtime and the exceptions it might throw, then it's okay to use the IList interface in this case; If they are willing to provide a really clean custom API in one go, then in this case they should show the implementation of the IList interface and publish a tailored read-only API. The latter is typical for collections exposed from the object model.

Although developers have complained about this situation, the new opportunities provided by generics far outweigh this crux and the problem is in . NET 4 was largely ignored before. However, this decision also sparked some reactions, which we will discuss later.

With the in. An exciting new feature in .NET 4 has been added to the runtime. In an earlier version. .NET, when interfaces become types, those interfaces are overly restricted. For example, even if Customer inherits from Person, it is not possible to pass an object of type IEnumerable <Customer>as a parameter to a function of type IEnumerable<Person>. With the addition of covariant support, this restriction was partially lifted.

We say "partially" because in some cases people should use some interface with a rich API all at once, rather than using an IEnumerable interface. Even if the IList interface is not covariant, a read-only list interface should be. Unfortunately, . The .NET base library team has again decided not to address this oversight.

Then the introduction of WinRT and the comeback of COM changed everything. COM interoperability was once a technology that developers would use when they had no other choice, but it has become a . The cornerstone of .NET programming. And since WinRT exposes the IVectorView <T>and IMapView<K, V> interfaces, therefore. .NET must also be adjusted accordingly.

One interesting feature of the WinRT program is the announcement of different but similar APIs for each development platform. As you may already know, all method names are represented by camelCased [2], while C++ and .NET developers see method names as PascalCased [3]. Another more drastic change is the automatic mapping between the C++ and .NET interfaces. Therefore. .NET developers don't need to deal with the Windows.Foundation.Collections namespace, just continue to use the System.Collections.Generic namespace. The IVectorView <T>and IMapView<K, V> interfaces will be converted by the runtime into IReadOnlyList <T>interfaces and IReadOnlyDictionary<TKey, TValue> interfaces, respectively.

It is worth noting that these interface names in C++/WinRT are more accurate to some extent. These interfaces are used to represent some views of a collection, but the interface does not ensure that the collection itself is immutable. Even among those with experienced. A common mistake among .NET developers is to assume that the ReadOnlyCollection type is a copy of an immutable collection, but in fact it is just a wrapper for an active collection (see Andrew Arnott's post of the same name for more information on read-only, frozen, and immutable collections).

Although the IList <T>interface has all the same members as the IReadOnlyList <T>interface, and all IList-type <T>lists can be represented as read-only lists, IList <T>does not inherit from IReadOnlyList<T>, which may be interesting to learn about. Immo Landwerth explained,

The reason it works is because those read-only interfaces are pure subsets of read-write interfaces, which seems like a reasonable assumption. Unfortunately, this assumption doesn't correspond to reality, as each method on each interface at the metadata level has its own slot (which makes explicit interface implementations work).

Or in other words, the only chance to introduce a read-only interface as some variable class base class is to fall back to . NET 2.0, i.e. when they were originally conceived. Once it's fully rolled out, the only change it can make is to add covariant and/or inverter markers (represented as "in" and "out" in VB and C#).

When asked why there is no IReadOnlyCollection <T>interface, Immo replied,

We considered this design, but we felt that adding a type that provided only the Count attribute would not add much value to the base library. In the base library team, we believe that if an API starts at minus 1000, then even providing some value is not enough to justify being added. The rationale for adding new APIs also includes a cost, for example, developers will have more concepts to choose from. At first we thought that adding this type would make the code perform better in certain scenarios where you just want to get a count and then do something interesting with it. For example, bulk add to an existing collection. However, in these scenarios, we have encouraged people to use only the IEnumerable <T>interface, and <T>for the special case of having an instance that implements the ICollection interface. Since all of our built-in collection types implemented this interface, there has been no performance gain in those most common scenarios. By the way, <T>the extension method Count() for IEnumerable can do this as well.

These new interfaces are available for . NET 4.5 and . NET for Windows 8。

Translation notes

[1] Base Class Library, abbreviated as BCL. For more information about the base class library, please participate in MSDN.

[2] camelCased, hump nomenclature, also known as lower camel case. The format is that the first word begins with a lowercase letter; The first letter of the second word is capitalized, for example: firstName, lastName.

[3] PascalCased, Pascal nomenclature, also known as the upper camel case. The format is that the first letter of each word is capitalized, for example: FirstName, LastName, CamelCase.




Previous:.NET/C# Software Licensing Platform [Source Code]
Next:JS Mining - How does Monero mine with web mining?
Disclaimer:
All software, programming materials or articles published by Code Farmer Network are only for learning and research purposes; The above content shall not be used for commercial or illegal purposes, otherwise, users shall bear all consequences. The information on this site comes from the Internet, and copyright disputes have nothing to do with this site. You must completely delete the above content from your computer within 24 hours of downloading. If you like the program, please support genuine software, purchase registration, and get better genuine services. If there is any infringement, please contact us by email.

Mail To:help@itsvse.com