Model of the. NET 2.0 basic class libraries--generic collections

Source: Internet
Author: User
Collection Generic Collection
There is no doubt that the most typical application of generics is the generic collection. A generic version of an existing collection class and interface is provided in. NET 2.0, which is located in the System.Collections.Generic namespace.

The new generic collection class in. NET 2.0 is not simply adding a generic parameter T to the design of an existing generic collection class. The design of the new generic collection class fully absorbs the rationality of the existing design and rejects some unreasonable places, and introduces a new design for the paradigm. Therefore, the design of the new generic class and interface should be more reasonable and effective, but. NET programmers need to spend some time learning new designs and understanding how different they are from existing designs, and the compatibility issues that can occur when porting code from a generic collection to a generic collection.

The following is a table (incomplete) of a generic set and an existing generic set:




Non-fan interface
Fan interface
Non-generic class
Model class

IEnumerator
Ienumerator<t>
ArrayList
List<t>

IEnumerable
Ienumerable<t>
Stack
Stack<t>

ICollection
Icollection<t>
Queue
Queue<t>

IList
Ilist<t>
DictionaryEntry
Keyvaluepair<k, v>

IDictionary
Idictionary<t>
Hashtable
Dictionary<k, v>

IComparable
Icomparable<t>
Comparer
Comparer<t>

IComparer
Icomparer<t>







You can see that some of the class names have been modified, for example, ArrayList now change to List<t>,hashtable to Dictionary<k, V>,dictionaryentry to KeyValuePair <k, v> and so on. Such naming is certainly more reasonable (since ilist<t> is an interface,list<t> is the corresponding concrete class; the same idictionary<k, V> is interface, Dictionary<k, v> is the corresponding concrete class While Keyvaluepair<k, v> is clearly easier to understand and remember than dictionaryentry, it may be a bit hard to find the north in the beginning for programmers who have become accustomed to the previous naming.

As I said earlier, the new generic set interface/class has a larger design change than the previous one, so let's look at these changes.

Ienumerator<t>
The Ienumerator/ienumerator<t> interface allows traversal of a collection, mainly in the traversal statements of the. NET programming language, such as the foreach statement of C #. User code typically does not use this interface directly. Ienumerator<t> is removed from the Reset method compared to the IEnumerator version. This may be due to the following considerations:

The L Ienumerator<t> interface is primarily designed to support statements such as foreach, where the Reset method is not used. Removing the Reset method makes the design simpler and reduces the difficulty of implementing the interface. If the caller needs a function like Reset, you can retrieve an enumerator (for example, by calling the GetEnumerator method).

L C # 2.0 iterators provides a way to generate enumerators automatically, and the compiler automatically implements the IEnumerator interface and ienumerator<t> interface for the specified class. The implementation of the Reset method for the IEnumerator interface simply throws the System.NotSupportedException exception. So it is natural and reasonable to remove the Reset method in the design of ienumerator<t>.

Icollection<t>
The design of the Icollection<t> interface changes significantly compared to the ICollection version. The initial design intent of the ICollection interface is to support the replication of collection elements (through the Count property and the CopyTo method), as well as to support synchronous access modes (through the issynchronized and SyncRoot properties). Icollection<t> 's design retains support for the elements of the replicated collection, but it rejects the support for synchronous access patterns because practice has proven that ICollection's synchronized access patterns are confusing and inefficient. A lot of just learn. NET programmer at first don't understand SyncRoot is what dongdong, what use. In addition, from a performance and logical point of view, it should be up to the caller to decide when to lock the collection, rather than being determined by the person implementing it. So in general issynchronized and SyncRoot are not ideal designs. Therefore,icollection<t> has no issynchronized properties and SyncRoot properties.

In addition,,icollection<t> has added new properties and methods that make the Icollection<t> interface more useful. These properties and methods are in fact ported from the common properties and methods of IList and IDictionary, including:

L IsReadOnly, used to determine whether the collection is read-only.

L Add/remove/clear, which is used to manage the collection elements. These methods are valid for both the list and the dictionary.

L Contains, used to determine whether the collection contains the specified value.

In addition, providing an interface like ireadonlycollection<t> might make sense for some usage scenarios that do not need to change the collection, it only needs to support the Count property, CopyTo method, and Contains method. However, Microsoft did not adopt such a design, the main reason is to make the basic set interface as simple as possible and easy to use. Microsoft's advice is for programmers to define such interfaces themselves.

Ilist<t> and List<t>
As mentioned earlier, the change of,ilist<t> relative to IList is a common attribute and method that is migrated into icollection<t>, leaving only the indexed-access properties and methods that are valid for the list.

List<t> has also made a great design change relative to ArrayList. The main consideration for making these changes is performance, because dynamic arrays are one of the most basic data structures used by. NET programs, and their performance affects the overall application. For example, the default Capacity for the previous ArrayList is 16, and List<t> 's default Capacity is 4, which minimizes the application's working set. Alternatively, the,list<t> method is not a virtual method (the ArrayList method is a virtual method), so that the function can be used inline to improve performance (virtual functions cannot be inline). List<t> also does not support the problem of Synchronized synchronous access mode.

An important feature of list<t> compared to ArrayList is the support for functional programming. We will introduce this new feature in the Functional programming section.

Idictionary<k, v> and Dictionary<k, v>
Idictionary<k, v> and dictionary<k, v> compared to the non-generic version, a big change is the processing logic of the indexer when the specified key does not exist. For IDictionary and Hashtable, the storage type of the value is object, and when the key does not exist, the indexer returns NULL, and returns NULL when the key exists and the corresponding value is null (the designer may think that the caller is usually concerned about whether the value is valid, Instead of distinguishing between the two cases. However, for a generic version, because the store may be a value type, NULL cannot be returned as an identity that does not exist as a key. Therefore, idictionary<k, v>, and dictionary<k, v> indexers will throw a KeyNotFoundException exception if the specified key does not exist. This will result in a source-level incompatibility, that is, the following code is not portable when the value type is stored, and must be overwritten (for example, by using the ContainsKey method to determine whether a specified key exists before accessing it, or by using a TryGetValue method that does not throw an exception):




Hashtable map = ...;

if (map["S1"] = = NULL) {//If a generic version will throw an exception instead of returning NULL

...

}




This question reflects the fact that the designer was not very thoughtful when designing the Hashtable class initially-using the Magic value NULL, either as a key nonexistent condition or as a key presence with null values, which is not true for the paradigm. In addition, from the design by Contract point of view, when the specified key value does not exist, it is natural to throw an exception (regardless of whether or not to use a paradigm), just as the array crosses the line. It is estimated that the original designer used null rather than exception handling primarily from a performance perspective.

Icomparable<t>,icomparer<t> and Comparer<t>
These several interfaces/classes are used for comparison and sorting. Icomparable<t> adds the Equals method compared to IComparable, of course, to minimize boxing (for value type classes). Icomparer<t> relative IComparer not only adds the Equals method, but also adds a new GetHashCode method. It seems to be less relevant than comparison, but in fact, for strings, comparisons and hashes are closely related. In the previous non-generic design, it was necessary to use both IComparer and ihashcodeprovider two interfaces, such as the Hashtable constructor:




Public Hashtable (IHashCodeProvider HCP, IComparer comparer);




Where the IHashCodeProvider and IComparer two parameters must match (for example, all use invariantcultureignorecase), otherwise the result will be incorrect. To allow programmers to quickly write the right code, the icomparer<t> now integrates the ability to compare and generate hash codes, such as Dictionary<k, v> constructors:




Public Dictionary (icomparer<k, v> comparer);




Comparer<k, V> provides icomparer<k, v> default implementation, Microsoft's latest design Guide recommends using Comparer<k, v> rather than other methods to compare and sort.

In addition, a new string comparison class--stringcomparer is added to. NET 2.0, located in the System namespace. StringComparer is not a generic class, but it implements the Icomparer<string> interface and is useful for strings that need to provide case-insensitive. For example, the following code creates a case-independent dictionary:




dictionary<string, int> dict = new dictionary<string, int> (stringcomparer.invariantcultureignorecase);

dict["Test" = 10;

int n = dict["Test"];



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.